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.TskCoreException;
/**
* Panel which allows viewing and selecting of Data Sources and some of their
* 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) {
List<DataSourceSummary> summaryList = new ArrayList<>();
final Map<Long, Long> artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts();
final Map<Long, Long> tagCountsMap = DataSourceInfoUtilities.getCountsOfTags();
try {
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()) {
summaryList.add(new DataSourceSummary(dataSource, usageMap.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
* expected to be in the datasource
*/
static Map<Long, String> getDataSourceTypes(SleuthkitCase skCase) {
static Map<Long, String> getDataSourceTypes() {
try {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
Map<Long, String> typeMap = new HashMap<>();
for (BlackboardArtifact typeArtifact : listOfArtifacts) {
@ -67,7 +68,7 @@ class DataSourceInfoUtilities {
}
}
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);
return Collections.emptyMap();
}
@ -83,16 +84,14 @@ class DataSourceInfoUtilities {
* files in the datasource, will only contain entries for
* datasources which have at least 1 file
*/
static Map<Long, Long> getCountsOfFiles(SleuthkitCase skCase) {
static Map<Long, Long> getCountsOfFiles() {
try {
DataSourceCountsCallback callback = new DataSourceCountsCallback();
final String countFilesQuery = "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 name<>'' GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countFilesQuery, callback);
return callback.getMapOfCounts();
} catch (TskCoreException ex) {
return getCountsMap(countFilesQuery);
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
@ -108,15 +107,13 @@ class DataSourceInfoUtilities {
* artifacts in the datasource, will only contain entries for
* datasources which have at least 1 artifact
*/
static Map<Long, Long> getCountsOfArtifacts(SleuthkitCase skCase) {
static Map<Long, Long> getCountsOfArtifacts() {
try {
DataSourceCountsCallback callback = new DataSourceCountsCallback();
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
+ " GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countArtifactsQuery, callback);
return callback.getMapOfCounts();
} catch (TskCoreException ex) {
return getCountsMap(countArtifactsQuery);
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
@ -133,28 +130,25 @@ class DataSourceInfoUtilities {
* tags which have been applied in the datasource, will only contain
* entries for datasources which have at least 1 item tagged.
*/
static Map<Long, Long> getCountsOfTags(SleuthkitCase skCase) {
static Map<Long, Long> getCountsOfTags() {
try {
DataSourceCountsCallback fileCountcallback = new DataSourceCountsCallback();
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
+ " GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countFileTagsQuery, fileCountcallback);
Map<Long, Long> tagCountMap = new HashMap<>(fileCountcallback.getMapOfCounts());
DataSourceCountsCallback artifactCountcallback = new DataSourceCountsCallback();
//new hashmap so it can be modifiable
Map<Long, Long> tagCountMap = new HashMap<>(getCountsMap(countFileTagsQuery));
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
+ " 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
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;
} catch (TskCoreException ex) {
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
}
}
/**
@ -199,7 +193,7 @@ class DataSourceInfoUtilities {
* specified mime types in the current case for the specified data
* 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) {
try {
String inClause = String.join("', '", setOfMimeTypes);
@ -217,6 +211,84 @@ class DataSourceInfoUtilities {
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() {
}
}

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
* 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<>();
@Override

View File

@ -19,18 +19,13 @@
package org.sleuthkit.autopsy.casemodule.datasourceSummary;
import java.awt.Frame;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.ListSelectionEvent;
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.SleuthkitCase;
/**
* Dialog for displaying the Data Sources Summary information
@ -55,15 +50,8 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
})
DataSourceSummaryDialog(Frame owner) {
super(owner, Bundle.DataSourceSummaryPanel_window_title(), true);
Map<Long, String> usageMap = new HashMap<>();
Map<Long, Long> fileCountsMap = new HashMap<>();
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);
}
Map<Long, String> usageMap = DataSourceInfoUtilities.getDataSourceTypes();
Map<Long, Long> fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles();
filesPanel = new DataSourceSummaryFilesPanel(fileCountsMap);
detailsPanel = new DataSourceSummaryDetailsPanel(usageMap);
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 FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null);
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
*/
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();
fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false);
}
@ -195,15 +202,15 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
} else if (columnIndex == 1) {
switch (rowIndex) {
case 0:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes());
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes());
case 1:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes());
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes());
case 2:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes());
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes());
case 3:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes());
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes());
case 4:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes());
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes());
default:
break;
}
@ -217,7 +224,7 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
}
}
/**
* Table model for the files table model to display counts of specific file
* types found in the currently selected data source.
@ -259,7 +266,7 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
"DataSourceSummaryFilesPanel.FilesByCategoryTableModel.unallocated.row=Unallocated",
"DataSourceSummaryFilesPanel.FilesByCategoryTableModel.slack.row=Slack",
"DataSourceSummaryFilesPanel.FilesByCategoryTableModel.directory.row=Directory"
})
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
@ -281,15 +288,23 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
} else if (columnIndex == 1) {
switch (rowIndex) {
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:
return 0;
Long unallocatedFilesCount = unallocatedFilesCountsMap.get(currentDataSource.getId());
Long allFilesCount = allFilesCountsMap.get(currentDataSource.getId());
if (allFilesCount == null) {
return 0;
} else if (unallocatedFilesCount == null) {
return allFilesCount;
} else {
return allFilesCount - unallocatedFilesCount;
}
case 2:
return 0;
return unallocatedFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : unallocatedFilesCountsMap.get(currentDataSource.getId());
case 3:
return 0;
return slackFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : slackFilesCountsMap.get(currentDataSource.getId());
case 4:
return 0;
return directoriesCountsMap.get(currentDataSource.getId()) == null ? 0 : directoriesCountsMap.get(currentDataSource.getId());
default:
break;
}