mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 08:26:15 +00:00
7938 finally fixed comment column and OS Account related code
This commit is contained in:
parent
bdcce7e1b5
commit
59e57bccde
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -137,6 +139,7 @@ public class CorrelationAttributeUtil {
|
|||||||
*/
|
*/
|
||||||
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(AnalysisResult analysisResult) {
|
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(AnalysisResult analysisResult) {
|
||||||
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
||||||
|
if (CentralRepository.isEnabled()) {
|
||||||
try {
|
try {
|
||||||
int artifactTypeID = analysisResult.getArtifactTypeID();
|
int artifactTypeID = analysisResult.getArtifactTypeID();
|
||||||
if (artifactTypeID == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
|
if (artifactTypeID == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
|
||||||
@ -186,6 +189,7 @@ public class CorrelationAttributeUtil {
|
|||||||
} catch (CentralRepoException ex) {
|
} catch (CentralRepoException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to get correlation type from central repository.", ex);
|
logger.log(Level.SEVERE, "Failed to get correlation type from central repository.", ex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return correlationAttrs;
|
return correlationAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +213,8 @@ public class CorrelationAttributeUtil {
|
|||||||
*/
|
*/
|
||||||
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(DataArtifact artifact) {
|
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(DataArtifact artifact) {
|
||||||
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
||||||
|
if (CentralRepository.isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
List<BlackboardAttribute> attributes = artifact.getAttributes();
|
List<BlackboardAttribute> attributes = artifact.getAttributes();
|
||||||
|
|
||||||
int artifactTypeID = artifact.getArtifactTypeID();
|
int artifactTypeID = artifact.getArtifactTypeID();
|
||||||
@ -298,6 +302,7 @@ public class CorrelationAttributeUtil {
|
|||||||
logger.log(Level.SEVERE, "Error getting current case", ex); // NON-NLS
|
logger.log(Level.SEVERE, "Error getting current case", ex); // NON-NLS
|
||||||
return correlationAttrs;
|
return correlationAttrs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return correlationAttrs;
|
return correlationAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +690,7 @@ public class CorrelationAttributeUtil {
|
|||||||
*/
|
*/
|
||||||
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(AbstractFile file) {
|
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(AbstractFile file) {
|
||||||
List<CorrelationAttributeInstance> fileTypeList = new ArrayList<>(); // will be an empty or single element list as was decided in 7852
|
List<CorrelationAttributeInstance> fileTypeList = new ArrayList<>(); // will be an empty or single element list as was decided in 7852
|
||||||
if (!isSupportedAbstractFileType(file)) {
|
if (!isSupportedAbstractFileType(file) || !CentralRepository.isEnabled()) {
|
||||||
return fileTypeList;
|
return fileTypeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,6 +759,7 @@ public class CorrelationAttributeUtil {
|
|||||||
|
|
||||||
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(OsAccountInstance osAccountInst) {
|
public static List<CorrelationAttributeInstance> makeCorrAttrsForSearch(OsAccountInstance osAccountInst) {
|
||||||
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
||||||
|
if (CentralRepository.isEnabled()) {
|
||||||
OsAccount account = null;
|
OsAccount account = null;
|
||||||
DataSource dataSource = null;
|
DataSource dataSource = null;
|
||||||
if (osAccountInst != null) {
|
if (osAccountInst != null) {
|
||||||
@ -791,9 +797,80 @@ public class CorrelationAttributeUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return correlationAttrs;
|
return correlationAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if any of the specified attribute values in the CR have a
|
||||||
|
* non-empty, non null comment.
|
||||||
|
*
|
||||||
|
* @param attributes The list of attributes to check the type value matches
|
||||||
|
* of for the presence of a comment.
|
||||||
|
*
|
||||||
|
* @return True if any the type value matches in the CR have a comment in
|
||||||
|
* their respective comment column, false if there are no comments
|
||||||
|
* or the CR is disabled.
|
||||||
|
*
|
||||||
|
* @throws CentralRepoException Thrown when there is an issue either getting
|
||||||
|
* the CentralRepository instance or executing
|
||||||
|
* a query.
|
||||||
|
*/
|
||||||
|
public static boolean commentExistsOnAttributes(List<CorrelationAttributeInstance> attributes) throws CentralRepoException {
|
||||||
|
boolean commentExists = false;
|
||||||
|
if (CentralRepository.isEnabled() && !attributes.isEmpty()) {
|
||||||
|
CentralRepository crInstance = CentralRepository.getInstance();
|
||||||
|
//Query to check for the presence of a comment on any matching value in the specified table.
|
||||||
|
String sqlSelect = "SELECT EXISTS "
|
||||||
|
+ "(SELECT 1 "
|
||||||
|
+ "FROM ";
|
||||||
|
String sqlWhere = " WHERE value=? "
|
||||||
|
+ "AND comment<>''"
|
||||||
|
+ "LIMIT 1)";
|
||||||
|
List<Object> params;
|
||||||
|
CommentExistsCallback commentCallback = new CommentExistsCallback();
|
||||||
|
for (CorrelationAttributeInstance instance : attributes) {
|
||||||
|
params = new ArrayList<>();
|
||||||
|
params.add(instance.getCorrelationValue());
|
||||||
|
String sql = sqlSelect + CentralRepoDbUtil.correlationTypeToInstanceTableName(instance.getCorrelationType()) + sqlWhere;
|
||||||
|
crInstance.executeQuery(sql, params, commentCallback);
|
||||||
|
if (commentCallback.doesCommentExist()) {
|
||||||
|
//we are checking a binary condition so as soon as any query returns true we can stop
|
||||||
|
commentExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return commentExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private implementation of the CentralRepositoryDbQueryCallback to parse
|
||||||
|
* the results of the query which checks if a type value pair has a comment.
|
||||||
|
*/
|
||||||
|
private static class CommentExistsCallback implements CentralRepositoryDbQueryCallback {
|
||||||
|
|
||||||
|
private boolean commentExists = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) throws CentralRepoException, SQLException {
|
||||||
|
//there should only be 1 result here with 1 column
|
||||||
|
if (rs.next()) {
|
||||||
|
commentExists = rs.getBoolean(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies if a comment existed.
|
||||||
|
*
|
||||||
|
* @return True if a comment existed, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean doesCommentExist() {
|
||||||
|
return commentExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent instantiation of this utility class.
|
* Prevent instantiation of this utility class.
|
||||||
*/
|
*/
|
||||||
|
@ -709,14 +709,22 @@ public final class CaseEventListener implements PropertyChangeListener {
|
|||||||
|
|
||||||
// Look up and create artifacts for previously seen accounts if requested
|
// Look up and create artifacts for previously seen accounts if requested
|
||||||
if (IngestEventsListener.isFlagSeenDevices()) {
|
if (IngestEventsListener.isFlagSeenDevices()) {
|
||||||
|
|
||||||
CorrelationAttributeInstance.Type osAcctType = CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID);
|
CorrelationAttributeInstance.Type osAcctType = CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID);
|
||||||
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(osAcctType, correlationAttributeInstances.get(0).getCorrelationValue());
|
CorrelationAttributeInstance instanceWithTypeValue = null;
|
||||||
|
for (CorrelationAttributeInstance instance : correlationAttributeInstances){
|
||||||
|
if (instance.getCorrelationType().getId() == CorrelationAttributeInstance.OSACCOUNT_TYPE_ID) {
|
||||||
|
instanceWithTypeValue = instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(instanceWithTypeValue.getCorrelationType(), instanceWithTypeValue.getCorrelationValue());
|
||||||
for (CorrelationAttributeInstance instance : previousOccurences) {
|
for (CorrelationAttributeInstance instance : previousOccurences) {
|
||||||
if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstances.get(0).getCorrelationCase().getCaseUUID())) {
|
//we can get the first instance here since the case for all attributes will be the same
|
||||||
|
if (!instance.getCorrelationCase().getCaseUUID().equals(instanceWithTypeValue.getCorrelationCase().getCaseUUID())) {
|
||||||
SleuthkitCase tskCase = osAccount.getSleuthkitCase();
|
SleuthkitCase tskCase = osAccount.getSleuthkitCase();
|
||||||
Blackboard blackboard = tskCase.getBlackboard();
|
Blackboard blackboard = tskCase.getBlackboard();
|
||||||
|
|
||||||
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(osAcctType, correlationAttributeInstances.get(0).getCorrelationValue());
|
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(osAcctType, instanceWithTypeValue.getCorrelationValue());
|
||||||
|
|
||||||
// calculate score
|
// calculate score
|
||||||
Score score;
|
Score score;
|
||||||
@ -741,7 +749,7 @@ public final class CaseEventListener implements PropertyChangeListener {
|
|||||||
osAcctType.getDisplayName()),
|
osAcctType.getDisplayName()),
|
||||||
new BlackboardAttribute(
|
new BlackboardAttribute(
|
||||||
TSK_CORRELATION_VALUE, MODULE_NAME,
|
TSK_CORRELATION_VALUE, MODULE_NAME,
|
||||||
correlationAttributeInstances.get(0).getCorrelationValue()),
|
instanceWithTypeValue.getCorrelationValue()),
|
||||||
new BlackboardAttribute(
|
new BlackboardAttribute(
|
||||||
TSK_OTHER_CASES, MODULE_NAME,
|
TSK_OTHER_CASES, MODULE_NAME,
|
||||||
prevCases));
|
prevCases));
|
||||||
|
@ -434,9 +434,9 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
|||||||
description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
|
description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
|
||||||
}
|
}
|
||||||
} catch (CentralRepoException ex) {
|
} catch (CentralRepoException ex) {
|
||||||
logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex);
|
logger.log(Level.SEVERE, "Error getting count of datasources with correlation attribute", ex);
|
||||||
} catch (CorrelationAttributeNormalizationException ex) {
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex);
|
logger.log(Level.SEVERE, "Unable to normalize data to get count of datasources with correlation attribute", ex);
|
||||||
}
|
}
|
||||||
return Pair.of(count, description);
|
return Pair.of(count, description);
|
||||||
}
|
}
|
||||||
@ -445,9 +445,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
|||||||
"AbstractAbstractFileNode.createSheet.comment.displayName=C"})
|
"AbstractAbstractFileNode.createSheet.comment.displayName=C"})
|
||||||
@Override
|
@Override
|
||||||
protected HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
protected HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
||||||
|
|
||||||
DataResultViewerTable.HasCommentStatus status = !tags.isEmpty() ? DataResultViewerTable.HasCommentStatus.TAG_NO_COMMENT : DataResultViewerTable.HasCommentStatus.NO_COMMENT;
|
DataResultViewerTable.HasCommentStatus status = !tags.isEmpty() ? DataResultViewerTable.HasCommentStatus.TAG_NO_COMMENT : DataResultViewerTable.HasCommentStatus.NO_COMMENT;
|
||||||
|
|
||||||
for (Tag tag : tags) {
|
for (Tag tag : tags) {
|
||||||
if (!StringUtils.isBlank(tag.getComment())) {
|
if (!StringUtils.isBlank(tag.getComment())) {
|
||||||
//if the tag is null or empty or contains just white space it will indicate there is not a comment
|
//if the tag is null or empty or contains just white space it will indicate there is not a comment
|
||||||
@ -455,17 +453,20 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attributes != null && !attributes.isEmpty()) {
|
/*
|
||||||
for (CorrelationAttributeInstance attribute : attributes) {
|
* Is there a comment in the CR for anything that matches the value and
|
||||||
if (attribute != null && !StringUtils.isBlank(attribute.getComment())) {
|
* type of the specified attributes.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
if (CorrelationAttributeUtil.commentExistsOnAttributes(attributes)) {
|
||||||
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
||||||
} else {
|
} else {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (CentralRepoException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Attempted to Query CR for presence of comments in a file node and was unable to perform query, comment column will only reflect caseDB", ex);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@ import java.util.List;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
|
|
||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -299,8 +299,12 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
|
|||||||
* sheet.
|
* sheet.
|
||||||
*/
|
*/
|
||||||
protected synchronized void updateSheet(NodeProperty<?>... newProps) {
|
protected synchronized void updateSheet(NodeProperty<?>... newProps) {
|
||||||
//Refresh ONLY those properties in the sheet currently. Subclasses may have
|
SwingUtilities.invokeLater(() -> {
|
||||||
//only added a subset of our properties or their own props.s
|
/*
|
||||||
|
* Refresh ONLY those properties in the sheet currently. Subclasses
|
||||||
|
* may have only added a subset of our properties or their own
|
||||||
|
* properties.
|
||||||
|
*/
|
||||||
Sheet visibleSheet = this.getSheet();
|
Sheet visibleSheet = this.getSheet();
|
||||||
Sheet.Set visibleSheetSet = visibleSheet.get(Sheet.PROPERTIES);
|
Sheet.Set visibleSheetSet = visibleSheet.get(Sheet.PROPERTIES);
|
||||||
Property<?>[] visibleProps = visibleSheetSet.getProperties();
|
Property<?>[] visibleProps = visibleSheetSet.getProperties();
|
||||||
@ -315,6 +319,7 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
|
|||||||
visibleSheet.put(visibleSheetSet);
|
visibleSheet.put(visibleSheetSet);
|
||||||
//setSheet() will notify Netbeans to update this node in the UI.
|
//setSheet() will notify Netbeans to update this node in the UI.
|
||||||
this.setSheet(visibleSheet);
|
this.setSheet(visibleSheet);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,6 +85,7 @@ import org.sleuthkit.datamodel.Tag;
|
|||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.autopsy.datamodel.utils.IconsUtil;
|
import org.sleuthkit.autopsy.datamodel.utils.IconsUtil;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||||
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
|
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
|
||||||
@ -881,9 +882,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the name of the source content of the artifact represented by
|
* Add the name of the source content of the artifact represented by
|
||||||
* this node to the sheet. The value of this property is the same as
|
* this node to the sheet. The value of this property is the same as the
|
||||||
* the display name of the node and this a "special" property that
|
* display name of the node and this a "special" property that displays
|
||||||
* displays the node's icon as well as the display name.
|
* the node's icon as well as the display name.
|
||||||
*/
|
*/
|
||||||
sheetSet.put(new NodeProperty<>(
|
sheetSet.put(new NodeProperty<>(
|
||||||
Bundle.BlackboardArtifactNode_createSheet_srcFile_name(),
|
Bundle.BlackboardArtifactNode_createSheet_srcFile_name(),
|
||||||
@ -1190,7 +1191,6 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Has a tag with a comment been applied to the artifact or its source
|
* Has a tag with a comment been applied to the artifact or its source
|
||||||
* content?
|
* content?
|
||||||
@ -1202,24 +1202,21 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Does the given correlation attribute instance have a comment in the
|
* Is there a comment in the CR for anything that matches the value and
|
||||||
* central repository?
|
* type of the specified attributes.
|
||||||
*/
|
*/
|
||||||
if (attributes != null && !attributes.isEmpty()) {
|
try {
|
||||||
for (CorrelationAttributeInstance attribute : attributes) {
|
if (CorrelationAttributeUtil.commentExistsOnAttributes(attributes)) {
|
||||||
if (attribute != null && !StringUtils.isBlank(attribute.getComment())) {
|
|
||||||
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
||||||
} else {
|
} else {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} catch (CentralRepoException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Attempted to Query CR for presence of comments in a Blackboard Artifact node and was unable to perform query, comment column will only reflect caseDB", ex);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,7 +1243,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
* Refreshes this node's property sheet.
|
* Refreshes this node's property sheet.
|
||||||
*/
|
*/
|
||||||
private void updateSheet() {
|
private void updateSheet() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
this.setSheet(createSheet());
|
this.setSheet(createSheet());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1524,8 +1523,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the SCO columns with the data retrieved in the background
|
* Update the SCO columns with the data retrieved in the background thread.
|
||||||
* thread.
|
|
||||||
*
|
*
|
||||||
* @param scoData The data for the SCO columns.
|
* @param scoData The data for the SCO columns.
|
||||||
*/
|
*/
|
||||||
|
@ -26,11 +26,16 @@ import java.util.List;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
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.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||||
import org.sleuthkit.datamodel.Score;
|
import org.sleuthkit.datamodel.Score;
|
||||||
@ -47,8 +52,6 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* content node.
|
* content node.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class GetSCOTask implements Runnable {
|
class GetSCOTask implements Runnable {
|
||||||
|
|
||||||
private final WeakReference<AbstractContentNode<?>> weakNodeRef;
|
private final WeakReference<AbstractContentNode<?>> weakNodeRef;
|
||||||
@ -71,14 +74,14 @@ class GetSCOTask implements Runnable {
|
|||||||
}
|
}
|
||||||
// get the SCO column values
|
// get the SCO column values
|
||||||
Pair<Score, String> scoreAndDescription;
|
Pair<Score, String> scoreAndDescription;
|
||||||
DataResultViewerTable.HasCommentStatus comment;
|
;
|
||||||
Pair<Long, String> countAndDescription = null;
|
Pair<Long, String> countAndDescription = null;
|
||||||
scoreAndDescription = contentNode.getScorePropertyAndDescription();
|
scoreAndDescription = contentNode.getScorePropertyAndDescription();
|
||||||
//getting the correlation attribute and setting the comment column is done before the eamdb isEnabled check
|
|
||||||
//because the Comment column will reflect the presence of comments in the CR when the CR is enabled, but reflect tag comments regardless
|
|
||||||
String description = Bundle.GetSCOTask_occurrences_defaultDescription();
|
String description = Bundle.GetSCOTask_occurrences_defaultDescription();
|
||||||
List<CorrelationAttributeInstance> listOfPossibleAttributes = new ArrayList<>();
|
List<CorrelationAttributeInstance> listOfPossibleAttributes = new ArrayList<>();
|
||||||
Content contentFromNode = contentNode.getContent();
|
Content contentFromNode = contentNode.getContent();
|
||||||
|
//the lists returned will be empty if the CR is not enabled
|
||||||
if (contentFromNode instanceof AbstractFile) {
|
if (contentFromNode instanceof AbstractFile) {
|
||||||
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) contentFromNode));
|
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) contentFromNode));
|
||||||
} else if (contentFromNode instanceof AnalysisResult) {
|
} else if (contentFromNode instanceof AnalysisResult) {
|
||||||
@ -86,17 +89,49 @@ class GetSCOTask implements Runnable {
|
|||||||
} else if (contentFromNode instanceof DataArtifact) {
|
} else if (contentFromNode instanceof DataArtifact) {
|
||||||
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) contentFromNode));
|
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) contentFromNode));
|
||||||
} else if (contentFromNode instanceof OsAccount) {
|
} else if (contentFromNode instanceof OsAccount) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<OsAccountInstance> osAccountInstances = ((OsAccount) contentFromNode).getOsAccountInstances();
|
List<OsAccountInstance> osAccountInstances = ((OsAccount) contentFromNode).getOsAccountInstances();
|
||||||
|
|
||||||
OsAccountInstance osAccountInstance = osAccountInstances.isEmpty() ? null : osAccountInstances.get(0);
|
OsAccountInstance osAccountInstance = osAccountInstances.isEmpty() ? null : osAccountInstances.get(0);
|
||||||
|
/*
|
||||||
|
* Because we are going to count cases the exact instance we get
|
||||||
|
* is not important.
|
||||||
|
*
|
||||||
|
* However since we are using the data source from this OS
|
||||||
|
* account instance to construct the correlation attribute
|
||||||
|
* instances we use to count cases, the presence of the data
|
||||||
|
* source in the CR will influence the count.
|
||||||
|
*
|
||||||
|
* So for consistancy we should always get an OS account
|
||||||
|
* instance with a data source in the CR if one is available,
|
||||||
|
* which necessitates the following code block currently.
|
||||||
|
*/
|
||||||
|
if (CentralRepository.isEnabled() && !osAccountInstances.isEmpty()) {
|
||||||
|
try {
|
||||||
|
CentralRepository centralRepo = CentralRepository.getInstance();
|
||||||
|
//Correlation Cases are cached when we get them so this shouldn't involve a round trip for every node.
|
||||||
|
CorrelationCase crCase = centralRepo.getCase(Case.getCurrentCaseThrows());
|
||||||
|
for (OsAccountInstance caseOsAccountInstance : osAccountInstances) {
|
||||||
|
//correlation data sources are also cached so once should not involve round trips every time.
|
||||||
|
CorrelationDataSource correlationDataSource = centralRepo.getDataSource(crCase, caseOsAccountInstance.getDataSource().getId());
|
||||||
|
if (correlationDataSource != null) {
|
||||||
|
//we have found a data source which exists in the CR we will use it instead of the arbitrary first instance
|
||||||
|
osAccountInstance = caseOsAccountInstance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CentralRepoException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error checking CR for data sources which exist in it", ex);
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "The current case was closed while attempting to find a data source in the central repository", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(osAccountInstance));
|
listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(osAccountInstance));
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Unable to get OsAccountInstances for OsAccount with ID: " + contentFromNode.getId(), ex);
|
logger.log(Level.WARNING, "Unable to get the DataSource or OsAccountInstances from an OsAccount with ID: " + contentFromNode.getId(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comment = contentNode.getCommentProperty(contentNode.getAllTagsFromDatabase(), listOfPossibleAttributes);
|
DataResultViewerTable.HasCommentStatus commentStatus = contentNode.getCommentProperty(contentNode.getAllTagsFromDatabase(), listOfPossibleAttributes);
|
||||||
|
|
||||||
CorrelationAttributeInstance corInstance = null;
|
CorrelationAttributeInstance corInstance = null;
|
||||||
if (CentralRepository.isEnabled()) {
|
if (CentralRepository.isEnabled()) {
|
||||||
if (listOfPossibleAttributes.size() > 1) {
|
if (listOfPossibleAttributes.size() > 1) {
|
||||||
@ -116,7 +151,7 @@ class GetSCOTask implements Runnable {
|
|||||||
listener.propertyChange(new PropertyChangeEvent(
|
listener.propertyChange(new PropertyChangeEvent(
|
||||||
AutopsyEvent.SourceType.LOCAL.toString(),
|
AutopsyEvent.SourceType.LOCAL.toString(),
|
||||||
AbstractAbstractFileNode.NodeSpecificEvents.SCO_AVAILABLE.toString(),
|
AbstractAbstractFileNode.NodeSpecificEvents.SCO_AVAILABLE.toString(),
|
||||||
null, new SCOData(scoreAndDescription, comment, countAndDescription)));
|
null, new SCOData(scoreAndDescription, commentStatus, countAndDescription)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ import org.openide.nodes.ChildFactory;
|
|||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.WeakListeners;
|
import org.openide.util.WeakListeners;
|
||||||
@ -47,6 +46,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -287,9 +287,7 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
Bundle.OsAccounts_accountHostNameProperty_desc(),
|
Bundle.OsAccounts_accountHostNameProperty_desc(),
|
||||||
hostsString));
|
hostsString));
|
||||||
}
|
}
|
||||||
|
updateSheet(propertiesToUpdate.toArray(new NodeProperty<?>[propertiesToUpdate.size()]));
|
||||||
SwingUtilities.invokeLater(()
|
|
||||||
-> updateSheet(propertiesToUpdate.toArray(new NodeProperty<?>[propertiesToUpdate.size()])));
|
|
||||||
} else if (evt.getPropertyName().equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
|
} else if (evt.getPropertyName().equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
|
||||||
SCOData scoData = (SCOData) evt.getNewValue();
|
SCOData scoData = (SCOData) evt.getNewValue();
|
||||||
if (scoData.getScoreAndDescription() != null) {
|
if (scoData.getScoreAndDescription() != null) {
|
||||||
@ -362,7 +360,9 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
* Refreshes this node's property sheet.
|
* Refreshes this node's property sheet.
|
||||||
*/
|
*/
|
||||||
void updateSheet() {
|
void updateSheet() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
this.setSheet(createSheet());
|
this.setSheet(createSheet());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -511,9 +511,8 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
OS_ACCOUNT_DATA_AVAILABLE_EVENT,
|
OS_ACCOUNT_DATA_AVAILABLE_EVENT,
|
||||||
null, evtData));
|
null, evtData));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
logger.log(Level.WARNING, "Error occurred getting realm information for Os Account Node from case db, for account: " + node.getOsAccount().getName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -536,9 +535,9 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
description = Bundle.OsAccounts_createSheet_count_hashLookupNotRun_description();
|
description = Bundle.OsAccounts_createSheet_count_hashLookupNotRun_description();
|
||||||
}
|
}
|
||||||
} catch (CentralRepoException ex) {
|
} catch (CentralRepoException ex) {
|
||||||
logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex);
|
logger.log(Level.SEVERE, "Error getting count of datasources with correlation attribute", ex);
|
||||||
} catch (CorrelationAttributeNormalizationException ex) {
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex);
|
logger.log(Level.SEVERE, "Unable to normalize data to get count of datasources with correlation attribute", ex);
|
||||||
}
|
}
|
||||||
return Pair.of(count, description);
|
return Pair.of(count, description);
|
||||||
}
|
}
|
||||||
@ -553,7 +552,6 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Has a tag with a comment been applied to the OsAccount or its
|
* Has a tag with a comment been applied to the OsAccount or its
|
||||||
* source content?
|
* source content?
|
||||||
@ -565,24 +563,21 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Does the given correlation attribute instance have a comment in
|
* Is there a comment in the CR for anything that matches the value
|
||||||
* the central repository?
|
* and type of the specified attributes.
|
||||||
*/
|
*/
|
||||||
if (attributes != null && !attributes.isEmpty()) {
|
try {
|
||||||
for (CorrelationAttributeInstance attribute : attributes) {
|
if (CorrelationAttributeUtil.commentExistsOnAttributes(attributes)) {
|
||||||
if (attribute != null && !StringUtils.isBlank(attribute.getComment())) {
|
|
||||||
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
|
||||||
} else {
|
} else {
|
||||||
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} catch (CentralRepoException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Attempted to Query CR for presence of comments in an OS Account node and was unable to perform query, comment column will only reflect caseDB", ex);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
@ -734,7 +735,6 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
|
|
||||||
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
|
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
|
||||||
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@Override
|
@Override
|
||||||
void handleReviewStatusChange(ReviewStatusChangeEvent event) {
|
void handleReviewStatusChange(ReviewStatusChangeEvent event) {
|
||||||
@ -1669,7 +1669,9 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateSheet() {
|
private void updateSheet() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
this.setSheet(createSheet());
|
this.setSheet(createSheet());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1846,7 +1848,9 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateSheet() {
|
private void updateSheet() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
this.setSheet(createSheet());
|
this.setSheet(createSheet());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user