mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge pull request #5896 from gdicristofaro/6359-removeCommenting
6359 remove commenting
This commit is contained in:
commit
137c3ff74d
@ -41,6 +41,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -105,7 +106,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
|
||||
private static final int QUERY_STR_MAX_LEN = 1000;
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the DB and initialize it.
|
||||
*
|
||||
@ -136,6 +136,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
* Get an ephemeral connection.
|
||||
*/
|
||||
protected abstract Connection getEphemeralConnection();
|
||||
|
||||
/**
|
||||
* Add a new name/value pair in the db_info table.
|
||||
*
|
||||
@ -222,7 +223,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
* Reset the contents of the caches associated with EamDb results.
|
||||
*/
|
||||
public final void clearCaches() {
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
typeCache.invalidateAll();
|
||||
isCRTypeCacheInitialized = false;
|
||||
}
|
||||
@ -1025,8 +1026,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
+ "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) "
|
||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
|
||||
+ getConflictClause();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sql = "INSERT INTO "
|
||||
+ tableName
|
||||
+ "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
|
||||
@ -1106,7 +1106,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException {
|
||||
try {
|
||||
@ -1116,18 +1115,15 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException {
|
||||
|
||||
Collection<CentralRepoAccountType> accountTypes = new ArrayList<>();
|
||||
|
||||
String sql = "SELECT * FROM account_types";
|
||||
try ( Connection conn = connect();
|
||||
try (Connection conn = connect();
|
||||
PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
|
||||
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery();) {
|
||||
while (resultSet.next()) {
|
||||
Account.Type acctType = new Account.Type(resultSet.getString("type_name"), resultSet.getString("display_name"));
|
||||
@ -1146,6 +1142,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
* Gets the CR account type for the specified type name.
|
||||
*
|
||||
* @param accountTypeName account type name to look for
|
||||
*
|
||||
* @return CR account type
|
||||
*
|
||||
* @throws CentralRepoException
|
||||
@ -1153,7 +1150,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException {
|
||||
|
||||
String sql = "SELECT * FROM account_types WHERE type_name = ?";
|
||||
try ( Connection conn = connect();
|
||||
try (Connection conn = connect();
|
||||
PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
|
||||
|
||||
preparedStatement.setString(1, accountTypeName);
|
||||
@ -1173,15 +1170,18 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CR account with the given account type and the unique account identifier.
|
||||
* Looks in the cache first.
|
||||
* If not found in cache, reads from the database and saves in cache.
|
||||
* Get the CR account with the given account type and the unique account
|
||||
* identifier. Looks in the cache first. If not found in cache, reads from
|
||||
* the database and saves in cache.
|
||||
*
|
||||
* Returns null if the account is not found in the cache and not in the database.
|
||||
* Returns null if the account is not found in the cache and not in the
|
||||
* database.
|
||||
*
|
||||
* @param crAccountType account type to look for
|
||||
* @param accountUniqueID unique account id
|
||||
* @return CentralRepoAccount for the give type/id. May return null if not found.
|
||||
*
|
||||
* @return CentralRepoAccount for the give type/id. May return null if not
|
||||
* found.
|
||||
*
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
@ -1198,10 +1198,9 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
return crAccount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Account with the given account type and account identifier,
|
||||
* from the database.
|
||||
* Get the Account with the given account type and account identifier, from
|
||||
* the database.
|
||||
*
|
||||
* @param accountType account type
|
||||
* @param accountUniqueID unique account identifier
|
||||
@ -1216,7 +1215,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
CentralRepoAccount account = null;
|
||||
|
||||
String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
|
||||
try ( Connection connection = connect();
|
||||
try (Connection connection = connect();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
|
||||
|
||||
preparedStatement.setInt(1, crAccountType.getAccountTypeId());
|
||||
@ -1234,7 +1233,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact) throws CentralRepoException {
|
||||
if (eamArtifact == null) {
|
||||
throw new CentralRepoException("CorrelationAttribute is null");
|
||||
@ -2002,8 +2000,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
String sqlUpdate
|
||||
= "UPDATE "
|
||||
+ tableName
|
||||
+ " SET known_status=?, comment=? "
|
||||
+ "WHERE id=?";
|
||||
+ " SET known_status=? WHERE id=?";
|
||||
|
||||
try {
|
||||
preparedQuery = conn.prepareStatement(sqlQuery);
|
||||
@ -2017,15 +2014,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
preparedUpdate = conn.prepareStatement(sqlUpdate);
|
||||
|
||||
preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
|
||||
// NOTE: if the user tags the same instance as BAD multiple times,
|
||||
// the comment from the most recent tagging is the one that will
|
||||
// prevail in the DB.
|
||||
if ("".equals(eamArtifact.getComment())) {
|
||||
preparedUpdate.setNull(2, Types.INTEGER);
|
||||
} else {
|
||||
preparedUpdate.setString(2, eamArtifact.getComment());
|
||||
}
|
||||
preparedUpdate.setInt(3, instance_id);
|
||||
preparedUpdate.setInt(2, instance_id);
|
||||
|
||||
preparedUpdate.executeUpdate();
|
||||
} else {
|
||||
@ -2332,8 +2321,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
HashHitInfo found = new HashHitInfo(hashFound, "", "");
|
||||
found.addComment(comment);
|
||||
return found;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -2345,8 +2333,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given value is in a specific reference set
|
||||
*
|
||||
@ -2737,15 +2723,16 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the examiner table for the given user name.
|
||||
* Adds a row if the user is not found in the examiner table.
|
||||
* Queries the examiner table for the given user name. Adds a row if the
|
||||
* user is not found in the examiner table.
|
||||
*
|
||||
* @param examinerLoginName user name to look for.
|
||||
*
|
||||
* @return CentralRepoExaminer for the given user name.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in looking up or
|
||||
* inserting the user in the examiners table.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException {
|
||||
|
||||
@ -3185,7 +3172,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
typeId = newCorrelationTypeKnownId(newType);
|
||||
}
|
||||
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
typeCache.put(newType.getId(), newType);
|
||||
}
|
||||
return typeId;
|
||||
@ -3402,7 +3389,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
|
||||
preparedStatement.setInt(5, aType.getId());
|
||||
preparedStatement.executeUpdate();
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
typeCache.put(aType.getId(), aType);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -3426,7 +3413,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
@Override
|
||||
public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws CentralRepoException {
|
||||
try {
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
|
||||
}
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
@ -3437,7 +3424,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the EamArtifact.Type that has the given Type.Id from the central repo
|
||||
*
|
||||
@ -3476,24 +3462,25 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the correlation types from the database and loads them up in the cache.
|
||||
* Reads the correlation types from the database and loads them up in the
|
||||
* cache.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error.
|
||||
*/
|
||||
private void getCorrelationTypesFromCr() throws CentralRepoException {
|
||||
|
||||
// clear out the cache
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
typeCache.invalidateAll();
|
||||
isCRTypeCacheInitialized = false;
|
||||
}
|
||||
|
||||
String sql = "SELECT * FROM correlation_types";
|
||||
try ( Connection conn = connect();
|
||||
try (Connection conn = connect();
|
||||
PreparedStatement preparedStatement = conn.prepareStatement(sql);
|
||||
ResultSet resultSet = preparedStatement.executeQuery();) {
|
||||
|
||||
synchronized(typeCache) {
|
||||
synchronized (typeCache) {
|
||||
while (resultSet.next()) {
|
||||
CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
|
||||
typeCache.put(aType.getId(), aType);
|
||||
|
@ -27,7 +27,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -55,6 +54,7 @@ import org.sleuthkit.datamodel.TagName;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.datamodel.Tag;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
|
||||
/**
|
||||
@ -147,6 +147,46 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tag has a notable status.
|
||||
*
|
||||
* @param t The tag to use in determination.
|
||||
*
|
||||
* @return Whether or not it is a notable tag.
|
||||
*/
|
||||
private static boolean isNotableTag(Tag t) {
|
||||
return (t != null && isNotableTagName(t.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tag name has a notable status.
|
||||
*
|
||||
* @param t The tag name to use in determination.
|
||||
*
|
||||
* @return Whether or not it is a notable tag name.
|
||||
*/
|
||||
private static boolean isNotableTagName(TagName t) {
|
||||
return (t != null && TagsManager.getNotableTagDisplayNames().contains(t.getDisplayName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a list of tags for a tag with a notable status.
|
||||
*
|
||||
* @param tags The tags to search.
|
||||
*
|
||||
* @return Whether or not the list contains a notable tag.
|
||||
*/
|
||||
private static boolean hasNotableTag(List<? extends Tag> tags) {
|
||||
if (tags == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tags.stream()
|
||||
.filter(CaseEventListener::isNotableTag)
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
private final class ContentTagTask implements Runnable {
|
||||
|
||||
private final CentralRepository dbManager;
|
||||
@ -163,72 +203,98 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractFile af;
|
||||
TskData.FileKnown knownStatus;
|
||||
String comment;
|
||||
if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.CONTENT_TAG_ADDED) {
|
||||
// For added tags, we want to change the known status to BAD if the
|
||||
// tag that was just added is in the list of central repo tags.
|
||||
final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) event;
|
||||
final ContentTag tagAdded = tagAddedEvent.getAddedTag();
|
||||
|
||||
if (TagsManager.getNotableTagDisplayNames().contains(tagAdded.getName().getDisplayName())) {
|
||||
if (tagAdded.getContent() instanceof AbstractFile) {
|
||||
af = (AbstractFile) tagAdded.getContent();
|
||||
knownStatus = TskData.FileKnown.BAD;
|
||||
comment = tagAdded.getComment();
|
||||
Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
|
||||
if (curEventType == Case.Events.CONTENT_TAG_ADDED && event instanceof ContentTagAddedEvent) {
|
||||
handleTagAdded((ContentTagAddedEvent) event);
|
||||
} else if (curEventType == Case.Events.CONTENT_TAG_DELETED && event instanceof ContentTagDeletedEvent) {
|
||||
handleTagDeleted((ContentTagDeletedEvent) event);
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Error updating non-file object");
|
||||
return;
|
||||
LOGGER.log(Level.SEVERE,
|
||||
String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
|
||||
event, curEventType));
|
||||
}
|
||||
} else {
|
||||
// The added tag isn't flagged as bad in central repo, so do nothing
|
||||
return;
|
||||
}
|
||||
} else { // CONTENT_TAG_DELETED
|
||||
// For deleted tags, we want to set the file status to UNKNOWN if:
|
||||
// - The tag that was just removed is notable in central repo
|
||||
// - There are no remaining tags that are notable
|
||||
final ContentTagDeletedEvent tagDeletedEvent = (ContentTagDeletedEvent) event;
|
||||
long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
|
||||
|
||||
String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
|
||||
if (!TagsManager.getNotableTagDisplayNames().contains(tagName)) {
|
||||
// If the tag that got removed isn't on the list of central repo tags, do nothing
|
||||
private void handleTagDeleted(ContentTagDeletedEvent evt) {
|
||||
// ensure tag deleted event has a valid content id
|
||||
if (evt.getDeletedTagInfo() == null) {
|
||||
LOGGER.log(Level.SEVERE, "ContentTagDeletedEvent did not have valid content to provide a content id.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the remaining tags on the content object
|
||||
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(contentID);
|
||||
TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
|
||||
List<ContentTag> tags = tagsManager.getContentTagsByContent(content);
|
||||
|
||||
if (tags.stream()
|
||||
.map(tag -> tag.getName().getDisplayName())
|
||||
.filter(TagsManager.getNotableTagDisplayNames()::contains)
|
||||
.collect(Collectors.toList())
|
||||
.isEmpty()) {
|
||||
|
||||
// There are no more bad tags on the object
|
||||
if (content instanceof AbstractFile) {
|
||||
af = (AbstractFile) content;
|
||||
knownStatus = TskData.FileKnown.UNKNOWN;
|
||||
comment = "";
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Error updating non-file object");
|
||||
// obtain content
|
||||
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
|
||||
if (content == null) {
|
||||
LOGGER.log(Level.WARNING,
|
||||
String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// There's still at least one bad tag, so leave the known status as is
|
||||
|
||||
// then handle the event
|
||||
handleTagChange(content);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
LOGGER.log(Level.WARNING, "Error updating non-file object: " + evt.getDeletedTagInfo().getContentID(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTagAdded(ContentTagAddedEvent evt) {
|
||||
// ensure tag added event has a valid content id
|
||||
if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null) {
|
||||
LOGGER.log(Level.SEVERE, "ContentTagAddedEvent did not have valid content to provide a content id.");
|
||||
return;
|
||||
}
|
||||
|
||||
// then handle the event
|
||||
handleTagChange(evt.getAddedTag().getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* When a tag is added or deleted, check if there are other notable tags
|
||||
* for the item. If there are, set known status as notable. If not set
|
||||
* status as unknown.
|
||||
*
|
||||
* @param content The content for the tag that was added or deleted.
|
||||
*/
|
||||
private void handleTagChange(Content content) {
|
||||
AbstractFile af = null;
|
||||
try {
|
||||
af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(content.getId());
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
Long contentID = (content != null) ? content.getId() : null;
|
||||
LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, ex);
|
||||
}
|
||||
|
||||
if (af == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the tags on the content object
|
||||
TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
|
||||
|
||||
if (hasNotableTag(tagsManager.getContentTagsByContent(content))) {
|
||||
// if there is a notable tag on the object, set content known status to bad
|
||||
setContentKnownStatus(af, TskData.FileKnown.BAD);
|
||||
} else {
|
||||
// otherwise, set to unknown
|
||||
setContentKnownStatus(af, TskData.FileKnown.UNKNOWN);
|
||||
}
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to find content", ex);
|
||||
return;
|
||||
LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the known status for the correlation attribute instance for the
|
||||
* given abstract file.
|
||||
*
|
||||
* @param af The abstract file for which to set the correlation
|
||||
* attribute instance.
|
||||
* @param knownStatus The new known status for the correlation attribute
|
||||
* instance.
|
||||
*/
|
||||
private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) {
|
||||
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af);
|
||||
|
||||
if (eamArtifact != null) {
|
||||
@ -239,7 +305,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
} // CONTENT_TAG_ADDED, CONTENT_TAG_DELETED
|
||||
}
|
||||
}
|
||||
|
||||
private final class BlackboardTagTask implements Runnable {
|
||||
@ -258,26 +324,71 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
Content content;
|
||||
BlackboardArtifact bbArtifact;
|
||||
TskData.FileKnown knownStatus;
|
||||
String comment;
|
||||
if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED) {
|
||||
// For added tags, we want to change the known status to BAD if the
|
||||
// tag that was just added is in the list of central repo tags.
|
||||
final BlackBoardArtifactTagAddedEvent tagAddedEvent = (BlackBoardArtifactTagAddedEvent) event;
|
||||
final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag();
|
||||
|
||||
if (TagsManager.getNotableTagDisplayNames().contains(tagAdded.getName().getDisplayName())) {
|
||||
content = tagAdded.getContent();
|
||||
bbArtifact = tagAdded.getArtifact();
|
||||
knownStatus = TskData.FileKnown.BAD;
|
||||
comment = tagAdded.getComment();
|
||||
Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
|
||||
if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED && event instanceof BlackBoardArtifactTagAddedEvent) {
|
||||
handleTagAdded((BlackBoardArtifactTagAddedEvent) event);
|
||||
} else if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED && event instanceof BlackBoardArtifactTagDeletedEvent) {
|
||||
handleTagDeleted((BlackBoardArtifactTagDeletedEvent) event);
|
||||
} else {
|
||||
// The added tag isn't flagged as bad in central repo, so do nothing
|
||||
LOGGER.log(Level.WARNING,
|
||||
String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
|
||||
event, curEventType));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTagDeleted(BlackBoardArtifactTagDeletedEvent evt) {
|
||||
// ensure tag deleted event has a valid content id
|
||||
if (evt.getDeletedTagInfo() == null) {
|
||||
LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagDeletedEvent did not have valid content to provide a content id.");
|
||||
return;
|
||||
}
|
||||
} else { //BLACKBOARD_ARTIFACT_TAG_DELETED
|
||||
|
||||
try {
|
||||
Case openCase = Case.getCurrentCaseThrows();
|
||||
|
||||
// obtain content
|
||||
Content content = openCase.getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
|
||||
if (content == null) {
|
||||
LOGGER.log(Level.WARNING,
|
||||
String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
|
||||
return;
|
||||
}
|
||||
|
||||
// obtain blackboard artifact
|
||||
BlackboardArtifact bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(evt.getDeletedTagInfo().getArtifactID());
|
||||
if (bbArtifact == null) {
|
||||
LOGGER.log(Level.WARNING,
|
||||
String.format("Unable to get blackboard artifact for item with artifact id: %d.", evt.getDeletedTagInfo().getArtifactID()));
|
||||
return;
|
||||
}
|
||||
|
||||
// then handle the event
|
||||
handleTagChange(content, bbArtifact);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
LOGGER.log(Level.WARNING, "Error updating non-file object.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTagAdded(BlackBoardArtifactTagAddedEvent evt) {
|
||||
// ensure tag added event has a valid content id
|
||||
if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null || evt.getAddedTag().getArtifact() == null) {
|
||||
LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagAddedEvent did not have valid content to provide a content id.");
|
||||
return;
|
||||
}
|
||||
|
||||
// then handle the event
|
||||
handleTagChange(evt.getAddedTag().getContent(), evt.getAddedTag().getArtifact());
|
||||
}
|
||||
|
||||
/**
|
||||
* When a tag is added or deleted, check if there are other notable tags
|
||||
* for the item. If there are, set known status as notable. If not set
|
||||
* status as unknown.
|
||||
*
|
||||
* @param content The content for the tag that was added or deleted.
|
||||
* @param bbArtifact The artifact for the tag that was added or deleted.
|
||||
*/
|
||||
private void handleTagChange(Content content, BlackboardArtifact bbArtifact) {
|
||||
Case openCase;
|
||||
try {
|
||||
openCase = Case.getCurrentCaseThrows();
|
||||
@ -285,60 +396,53 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex);
|
||||
return;
|
||||
}
|
||||
// For deleted tags, we want to set the file status to UNKNOWN if:
|
||||
// - The tag that was just removed is notable in central repo
|
||||
// - There are no remaining tags that are notable
|
||||
final BlackBoardArtifactTagDeletedEvent tagDeletedEvent = (BlackBoardArtifactTagDeletedEvent) event;
|
||||
long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
|
||||
long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID();
|
||||
|
||||
String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
|
||||
if (!TagsManager.getNotableTagDisplayNames().contains(tagName)) {
|
||||
// If the tag that got removed isn't on the list of central repo tags, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the remaining tags on the artifact
|
||||
content = openCase.getSleuthkitCase().getContentById(contentID);
|
||||
bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(artifactID);
|
||||
if (isKnownFile(content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TagsManager tagsManager = openCase.getServices().getTagsManager();
|
||||
List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
|
||||
|
||||
if (tags.stream()
|
||||
.map(tag -> tag.getName().getDisplayName())
|
||||
.filter(TagsManager.getNotableTagDisplayNames()::contains)
|
||||
.collect(Collectors.toList())
|
||||
.isEmpty()) {
|
||||
|
||||
// There are no more bad tags on the object
|
||||
knownStatus = TskData.FileKnown.UNKNOWN;
|
||||
comment = "";
|
||||
|
||||
if (hasNotableTag(tags)) {
|
||||
setArtifactKnownStatus(bbArtifact, TskData.FileKnown.BAD);
|
||||
} else {
|
||||
// There's still at least one bad tag, so leave the known status as is
|
||||
return;
|
||||
setArtifactKnownStatus(bbArtifact, TskData.FileKnown.UNKNOWN);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to find content", ex);
|
||||
LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) {
|
||||
return;
|
||||
/**
|
||||
* Determines if the content is an abstract file and is a known file.
|
||||
*
|
||||
* @param content The content to assess.
|
||||
*
|
||||
* @return True if an abstract file and a known file.
|
||||
*/
|
||||
private boolean isKnownFile(Content content) {
|
||||
return ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the known status of a blackboard artifact in the central
|
||||
* repository.
|
||||
*
|
||||
* @param bbArtifact The blackboard artifact to set known status.
|
||||
* @param knownStatus The new known status.
|
||||
*/
|
||||
private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) {
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact);
|
||||
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) {
|
||||
eamArtifact.setComment(comment);
|
||||
try {
|
||||
dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus);
|
||||
} catch (CentralRepoException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
} // BLACKBOARD_ARTIFACT_TAG_ADDED, BLACKBOARD_ARTIFACT_TAG_DELETED
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -440,7 +544,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
if (!hasTagWithConflictingKnownStatus) {
|
||||
Content taggedContent = contentTag.getContent();
|
||||
if (taggedContent instanceof AbstractFile) {
|
||||
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile)taggedContent);
|
||||
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile) taggedContent);
|
||||
if (eamArtifact != null) {
|
||||
CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user