7938 finally fixed comment column and OS Account related code

This commit is contained in:
William Schaefer 2021-09-29 23:07:38 -04:00
parent bdcce7e1b5
commit 59e57bccde
8 changed files with 396 additions and 273 deletions

View File

@ -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,54 +139,56 @@ 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<>();
try { if (CentralRepository.isEnabled()) {
int artifactTypeID = analysisResult.getArtifactTypeID(); try {
if (artifactTypeID == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { int artifactTypeID = analysisResult.getArtifactTypeID();
BlackboardAttribute assocArtifactAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT); if (artifactTypeID == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
if (assocArtifactAttr != null) { BlackboardAttribute assocArtifactAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT);
BlackboardArtifact sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong()); if (assocArtifactAttr != null) {
if (sourceArtifact instanceof DataArtifact) { BlackboardArtifact sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong());
correlationAttrs.addAll((CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) sourceArtifact))); if (sourceArtifact instanceof DataArtifact) {
} else if (sourceArtifact instanceof AnalysisResult) { correlationAttrs.addAll((CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) sourceArtifact)));
correlationAttrs.addAll((CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) sourceArtifact))); } else if (sourceArtifact instanceof AnalysisResult) {
} else { correlationAttrs.addAll((CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) sourceArtifact)));
String sourceName = sourceArtifact != null ? "SourceArtifact display name: " + sourceArtifact.getDisplayName() : "SourceArtifact was null"; } else {
logger.log(Level.WARNING, "Source artifact found through TSK_ASSOCIATED_ARTIFACT attribute was not a DataArtifact or " String sourceName = sourceArtifact != null ? "SourceArtifact display name: " + sourceArtifact.getDisplayName() : "SourceArtifact was null";
+ "an Analysis Result. AssociateArtifactAttr Value: {0} {1}", logger.log(Level.WARNING, "Source artifact found through TSK_ASSOCIATED_ARTIFACT attribute was not a DataArtifact or "
new Object[]{assocArtifactAttr.getValueString(), sourceName}); + "an Analysis Result. AssociateArtifactAttr Value: {0} {1}",
} new Object[]{assocArtifactAttr.getValueString(), sourceName});
}
}
} else {
if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
BlackboardAttribute setNameAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_SET_NAME);
if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(analysisResult, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, analysisResult.getAttributes()));
} }
} } else {
Content parent = analysisResult.getParent(); if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
if (parent instanceof AbstractFile) { BlackboardAttribute setNameAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_SET_NAME);
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) parent)); if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) {
} else if (parent instanceof AnalysisResult) { correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(analysisResult, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, analysisResult.getAttributes()));
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) parent)); }
} else if (parent instanceof DataArtifact) { }
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) parent)); Content parent = analysisResult.getParent();
} else if (parent instanceof OsAccount) { if (parent instanceof AbstractFile) {
for (OsAccountInstance osAccountInst : ((OsAccount) parent).getOsAccountInstances()) { correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) parent));
if (osAccountInst.getDataSource().equals(analysisResult.getDataSource())) { } else if (parent instanceof AnalysisResult) {
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(osAccountInst)); correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) parent));
break; } else if (parent instanceof DataArtifact) {
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) parent));
} else if (parent instanceof OsAccount) {
for (OsAccountInstance osAccountInst : ((OsAccount) parent).getOsAccountInstances()) {
if (osAccountInst.getDataSource().equals(analysisResult.getDataSource())) {
correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(osAccountInst));
break;
}
} }
} }
} }
}
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get information regarding correlation attributes from AnalysisResult", ex); logger.log(Level.SEVERE, "Failed to get information regarding correlation attributes from AnalysisResult", ex);
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Attempted to retrieve correlation attributes for search with no currently open case.", ex); logger.log(Level.SEVERE, "Attempted to retrieve correlation attributes for search with no currently open case.", ex);
} 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,94 +213,95 @@ 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<>();
try { if (CentralRepository.isEnabled()) {
try {
List<BlackboardAttribute> attributes = artifact.getAttributes();
List<BlackboardAttribute> attributes = artifact.getAttributes(); int artifactTypeID = artifact.getArtifactTypeID();
if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) {
BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN));
if ((domainAttr != null)
&& !domainsToSkip.contains(domainAttr.getValueString())) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes));
}
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID,
attributes, sourceContent, dataSource));
int artifactTypeID = artifact.getArtifactTypeID(); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) {
if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
if ((domainAttr != null) Content dataSource = sourceContent.getDataSource();
&& !domainsToSkip.contains(domainAttr.getValueString())) { correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID,
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes)); attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
makeCorrAttrFromAcctArtifact(correlationAttrs, artifact);
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH));
String pathAttrString = null;
if (setNameAttr != null) {
pathAttrString = setNameAttr.getValueString();
}
if (pathAttrString != null && !pathAttrString.isEmpty()) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes));
} else {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes));
}
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
correlationAttrs.addAll(makeCorrAttrsFromCommunicationArtifact(artifact, attributes));
} }
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { } catch (CorrelationAttributeNormalizationException ex) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times logger.log(Level.WARNING, String.format("Error normalizing correlation attribute (%s)", artifact), ex); // NON-NLS
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); return correlationAttrs;
Content dataSource = sourceContent.getDataSource(); } catch (InvalidAccountIDException ex) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, logger.log(Level.WARNING, String.format("Invalid account identifier (artifactID: %d)", artifact.getId())); // NON-NLS
attributes, sourceContent, dataSource)); return correlationAttrs;
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, } catch (CentralRepoException ex) {
attributes, sourceContent, dataSource)); logger.log(Level.SEVERE, String.format("Error querying central repository (%s)", artifact), ex); // NON-NLS
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) { return correlationAttrs;
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes)); } catch (TskCoreException ex) {
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID() logger.log(Level.SEVERE, String.format("Error getting querying case database (%s)", artifact), ex); // NON-NLS
|| artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() return correlationAttrs;
|| artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) { } catch (NoCurrentCaseException ex) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes)); logger.log(Level.SEVERE, "Error getting current case", ex); // NON-NLS
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { return correlationAttrs;
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) {
// prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times
Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
Content dataSource = sourceContent.getDataSource();
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID,
attributes, sourceContent, dataSource));
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID,
attributes, sourceContent, dataSource));
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
makeCorrAttrFromAcctArtifact(correlationAttrs, artifact);
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH));
String pathAttrString = null;
if (setNameAttr != null) {
pathAttrString = setNameAttr.getValueString();
}
if (pathAttrString != null && !pathAttrString.isEmpty()) {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes));
} else {
correlationAttrs.addAll(makeCorrAttrFromArtifactAttr(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes));
}
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
correlationAttrs.addAll(makeCorrAttrsFromCommunicationArtifact(artifact, attributes));
} }
} catch (CorrelationAttributeNormalizationException ex) {
logger.log(Level.WARNING, String.format("Error normalizing correlation attribute (%s)", artifact), ex); // NON-NLS
return correlationAttrs;
} catch (InvalidAccountIDException ex) {
logger.log(Level.WARNING, String.format("Invalid account identifier (artifactID: %d)", artifact.getId())); // NON-NLS
return correlationAttrs;
} catch (CentralRepoException ex) {
logger.log(Level.SEVERE, String.format("Error querying central repository (%s)", artifact), ex); // NON-NLS
return correlationAttrs;
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting querying case database (%s)", artifact), ex); // NON-NLS
return correlationAttrs;
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Error getting current case", ex); // NON-NLS
return correlationAttrs;
} }
return correlationAttrs; return correlationAttrs;
} }
@ -543,7 +548,7 @@ public class CorrelationAttributeUtil {
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows()); CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID() if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()
|| ! (srcContent instanceof AbstractFile)) { || !(srcContent instanceof AbstractFile)) {
return new CorrelationAttributeInstance( return new CorrelationAttributeInstance(
correlationType, correlationType,
value, value,
@ -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,46 +759,118 @@ 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<>();
OsAccount account = null; if (CentralRepository.isEnabled()) {
DataSource dataSource = null; OsAccount account = null;
if (osAccountInst != null) { DataSource dataSource = null;
try { if (osAccountInst != null) {
account = osAccountInst.getOsAccount();
dataSource = osAccountInst.getDataSource();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting information from OsAccountInstance.", ex);
}
}
if (account != null && dataSource != null) {
Optional<String> accountAddr = account.getAddr();
// Check address if it is null or one of the ones below we want to ignore it since they will always be one a windows system
// and they are not unique
if (accountAddr.isPresent() && !accountAddr.get().equals("S-1-5-18") && !accountAddr.get().equals("S-1-5-19") && !accountAddr.get().equals("S-1-5-20")) {
try { try {
account = osAccountInst.getOsAccount();
dataSource = osAccountInst.getDataSource();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting information from OsAccountInstance.", ex);
}
}
if (account != null && dataSource != null) {
Optional<String> accountAddr = account.getAddr();
// Check address if it is null or one of the ones below we want to ignore it since they will always be one a windows system
// and they are not unique
if (accountAddr.isPresent() && !accountAddr.get().equals("S-1-5-18") && !accountAddr.get().equals("S-1-5-19") && !accountAddr.get().equals("S-1-5-20")) {
try {
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows()); CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
accountAddr.get(), accountAddr.get(),
correlationCase, correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource), CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource),
"", "",
"", "",
TskData.FileKnown.KNOWN, TskData.FileKnown.KNOWN,
account.getId()); account.getId());
correlationAttrs.add(correlationAttributeInstance); correlationAttrs.add(correlationAttributeInstance);
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
logger.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS logger.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
} catch (CorrelationAttributeNormalizationException ex) { } catch (CorrelationAttributeNormalizationException ex) {
logger.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS logger.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS
}
} }
} }
} }
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.
*/ */

View File

@ -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));

View File

@ -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.
if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) { */
status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS; try {
} else { if (CorrelationAttributeUtil.commentExistsOnAttributes(attributes)) {
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT; if (status == DataResultViewerTable.HasCommentStatus.TAG_COMMENT) {
} status = DataResultViewerTable.HasCommentStatus.CR_AND_TAG_COMMENTS;
break; } else {
status = DataResultViewerTable.HasCommentStatus.CR_COMMENT;
} }
} }
} 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;
} }

View File

@ -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,22 +299,27 @@ 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 /*
Sheet visibleSheet = this.getSheet(); * Refresh ONLY those properties in the sheet currently. Subclasses
Sheet.Set visibleSheetSet = visibleSheet.get(Sheet.PROPERTIES); * may have only added a subset of our properties or their own
Property<?>[] visibleProps = visibleSheetSet.getProperties(); * properties.
for (NodeProperty<?> newProp : newProps) { */
for (int i = 0; i < visibleProps.length; i++) { Sheet visibleSheet = this.getSheet();
if (visibleProps[i].getName().equals(newProp.getName())) { Sheet.Set visibleSheetSet = visibleSheet.get(Sheet.PROPERTIES);
visibleProps[i] = newProp; Property<?>[] visibleProps = visibleSheetSet.getProperties();
for (NodeProperty<?> newProp : newProps) {
for (int i = 0; i < visibleProps.length; i++) {
if (visibleProps[i].getName().equals(newProp.getName())) {
visibleProps[i] = newProp;
}
} }
} }
} visibleSheetSet.put(visibleProps);
visibleSheetSet.put(visibleProps); 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); });
} }
/** /**

View File

@ -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;
@ -880,16 +881,16 @@ 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(),
Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(),
NO_DESCR, NO_DESCR,
getDisplayName())); getDisplayName()));
GetSCOTask scoTask = null; GetSCOTask scoTask = null;
if (artifact instanceof AnalysisResult if (artifact instanceof AnalysisResult
@ -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() {
this.setSheet(createSheet()); SwingUtilities.invokeLater(() -> {
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.
*/ */
@ -1562,17 +1560,17 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
* Sets the displayName of the node based on the source content. * Sets the displayName of the node based on the source content.
*/ */
private void setDisplayNameBySourceContent() { private void setDisplayNameBySourceContent() {
if(srcContent instanceof BlackboardArtifact) { if (srcContent instanceof BlackboardArtifact) {
try { try {
setDisplayName(((BlackboardArtifact)srcContent).getShortDescription()); setDisplayName(((BlackboardArtifact) srcContent).getShortDescription());
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
// Log the error, but set the display name to // Log the error, but set the display name to
// Content.getName so there is something visible to the user. // Content.getName so there is something visible to the user.
logger.log(Level.WARNING, "Failed to get short description for artifact id = " + srcContent.getId(), ex); logger.log(Level.WARNING, "Failed to get short description for artifact id = " + srcContent.getId(), ex);
setDisplayName(srcContent.getName()); setDisplayName(srcContent.getName());
} }
} else if(srcContent instanceof OsAccount) { } else if (srcContent instanceof OsAccount) {
setDisplayName(((OsAccount)srcContent).getAddr().orElse(srcContent.getName())); setDisplayName(((OsAccount) srcContent).getAddr().orElse(srcContent.getName()));
} else { } else {
setDisplayName(srcContent.getName()); setDisplayName(srcContent.getName());
} }

View File

@ -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)));
} }
} }
} }

View File

@ -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() {
this.setSheet(createSheet()); SwingUtilities.invokeLater(() -> {
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;
} }

View File

@ -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) {
@ -1117,7 +1117,7 @@ final public class Accounts implements AutopsyVisitableItem {
} }
@Override @Override
protected void finalize() throws Throwable{ protected void finalize() throws Throwable {
super.finalize(); super.finalize();
IngestManager.getInstance().removeIngestJobEventListener(weakPcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
@ -1669,7 +1669,9 @@ final public class Accounts implements AutopsyVisitableItem {
} }
private void updateSheet() { private void updateSheet() {
this.setSheet(createSheet()); SwingUtilities.invokeLater(() -> {
this.setSheet(createSheet());
});
} }
} }
@ -1846,7 +1848,9 @@ final public class Accounts implements AutopsyVisitableItem {
} }
private void updateSheet() { private void updateSheet() {
this.setSheet(createSheet()); SwingUtilities.invokeLater(() -> {
this.setSheet(createSheet());
});
} }
} }