From 1436cad2ec51fee4087069c821a9b0bb218d0a5a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 11 May 2020 14:34:53 -0400 Subject: [PATCH 1/6] removed comments from upload in setAttributeInstanceKnownStatus --- .../datamodel/RdbmsCentralRepo.java | 21 +- .../eventlisteners/CaseEventListener.java | 371 +++++++++++------- 2 files changed, 240 insertions(+), 152 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index de88396de7..c00e6dec62 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -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; @@ -1999,11 +2000,11 @@ abstract class RdbmsCentralRepo implements CentralRepository { + "AND file_path=?"; String sqlUpdate - = "UPDATE " - + tableName - + " SET known_status=?, comment=? " - + "WHERE id=?"; - + = "UPDATE " + + tableName + + " SET known_status=? WHERE id=?"; + + try { preparedQuery = conn.prepareStatement(sqlQuery); preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID()); @@ -2016,15 +2017,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 { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index d8bd1c43c3..13a9fce3ab 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -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; /** * Listen for case events and update entries in the Central Repository database @@ -66,12 +66,12 @@ final class CaseEventListener implements PropertyChangeListener { private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName()); private final ExecutorService jobProcessingExecutor; private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d"; - + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, - Case.Events.DATA_SOURCE_ADDED, + Case.Events.DATA_SOURCE_ADDED, Case.Events.TAG_DEFINITION_CHANGED, Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_NAME_CHANGED); @@ -93,7 +93,7 @@ final class CaseEventListener implements PropertyChangeListener { LOGGER.log(Level.SEVERE, "Failed to get instance of db manager.", ex); return; } - + // If any changes are made to which event types are handled the change // must also be made to CASE_EVENTS_OF_INTEREST. switch (Case.Events.valueOf(evt.getPropertyName())) { @@ -127,7 +127,7 @@ final class CaseEventListener implements PropertyChangeListener { break; } } - + /* * Add all of our Case Event Listeners to the case. */ @@ -142,6 +142,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 tags) { + if (tags == null) { + return false; + } + + return tags.stream() + .filter(CaseEventListener::isNotableTag) + .findFirst() + .isPresent(); + } + private final class ContentTagTask implements Runnable { private final CentralRepository dbManager; @@ -158,73 +198,99 @@ 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(); + 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, + String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.", + event, curEventType)); + } + } - if (TagsManager.getNotableTagDisplayNames().contains(tagAdded.getName().getDisplayName())) { - if (tagAdded.getContent() instanceof AbstractFile) { - af = (AbstractFile) tagAdded.getContent(); - knownStatus = TskData.FileKnown.BAD; - comment = tagAdded.getComment(); - } else { - LOGGER.log(Level.WARNING, "Error updating non-file object"); - return; - } - } 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(); + /** + * When a tag is added, handle whether or not to add/update the central + * repository correlation attribute instance for the file. A correlation + * attribute instance will be created / updated if the tag is notable. + * + * @param tagAddedEvent The event where a tag was added. + */ + private void handleTagAdded(ContentTagAddedEvent tagAddedEvent) { + final ContentTag tagAdded = tagAddedEvent.getAddedTag(); - 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 content object - Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(contentID); - TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager(); - List 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"); - return; - } - } else { - // There's still at least one bad tag, so leave the known status as is - return; - } - } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, "Failed to find content", ex); - return; - } + if (!isNotableTag(tagAdded)) { + return; } + AbstractFile af = null; + try { + af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(tagAdded.getContent().getId()); + } catch (NoCurrentCaseException | TskCoreException ex) { + LOGGER.log(Level.WARNING, "Error updating non-file object"); + } + + if (af == null) { + return; + } + + setContentKnownStatus(af, TskData.FileKnown.BAD); + } + + /** + * For deleted tags, set the central repository correlation attribute + * instance file status to unknown if the tag that was deleted was the + * only tag on the file that confers notability. + * + * @param tagDeletedEvent The tag deleted event containing information + * about the tag that is being deleted. + */ + private void handleTagDeleted(ContentTagDeletedEvent tagDeletedEvent) { + if (!isNotableTagName(tagDeletedEvent.getDeletedTagInfo().getName())) { + // If the tag that got removed isn't on the list of central repo tags, do nothing + return; + } + + long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID(); + + try { + // Get the remaining tags on the content object + Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(contentID); + TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager(); + + if (hasNotableTag(tagsManager.getContentTagsByContent(content))) { + // There's still at least one bad tag, so leave the known status as is + return; + } + + // There are no more bad tags on the object + AbstractFile af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(contentID); + if (af == null) { + LOGGER.log(Level.WARNING, "Error updating non-file object"); + return; + } + + setContentKnownStatus(af, TskData.FileKnown.UNKNOWN); + + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, "Failed to find content", ex); + return; + } + } + + /** + * 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); + eamArtifact.setComment(""); if (eamArtifact != null) { // send update to Central Repository db @@ -234,7 +300,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 { @@ -253,87 +319,116 @@ 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(); - } else { - // The added tag isn't flagged as bad in central repo, so do nothing - return; - } - } else { //BLACKBOARD_ARTIFACT_TAG_DELETED - Case openCase; - try { - openCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - 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); - TagsManager tagsManager = openCase.getServices().getTagsManager(); - List 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 = ""; - - } else { - // There's still at least one bad tag, so leave the known status as is - return; - } - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to find content", ex); - return; - } + 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 { + 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)); } + } - if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) { + /** + * When a tag is added, handle whether or not to add/update the central + * repository correlation attribute instance for the artifact. A + * correlation attribute instance will be created / updated if the tag + * is notable and the file is not known. + * + * @param tagAddedEvent The event where a tag was added. + */ + private void handleTagAdded(BlackBoardArtifactTagAddedEvent tagAddedEvent) { + final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag(); + + // The added tag isn't flagged as bad in central repo, so do nothing + if (!isNotableTag(tagAdded)) { return; } + if (isKnownFile(tagAdded.getContent())) { + return; + } + + setArtifactKnownStatus(tagAdded.getArtifact(), TskData.FileKnown.BAD); + } + + /** + * For deleted tags, set the central repository correlation attribute + * instance file status to unknown if the tag that was deleted was the + * only tag on the file that confers notability. + * + * @param tagDeletedEvent The tag deleted event containing information + * about the tag that is begin deleted. + */ + private void handleTagDeleted(BlackBoardArtifactTagDeletedEvent tagDeletedEvent) { + if (!isNotableTagName(tagDeletedEvent.getDeletedTagInfo().getName())) { + // If the tag that got removed isn't on the list of central repo tags, do nothing + return; + } + + Case openCase; + try { + openCase = Case.getCurrentCaseThrows(); + } catch (NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); + return; + } + + long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID(); + long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID(); + + try { + // Get the remaining tags on the artifact + Content content = openCase.getSleuthkitCase().getContentById(contentID); + if (isKnownFile(content)) { + return; + } + + BlackboardArtifact bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(artifactID); + TagsManager tagsManager = openCase.getServices().getTagsManager(); + List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact); + if (hasNotableTag(tags)) { + return; + } + + setArtifactKnownStatus(bbArtifact, TskData.FileKnown.UNKNOWN); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to find content", ex); + 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 convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { - eamArtifact.setComment(comment); + eamArtifact.setComment(""); 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 + } } @@ -434,8 +529,8 @@ final class CaseEventListener implements PropertyChangeListener { //if the file will have no tags with a status which would prevent the current status from being changed if (!hasTagWithConflictingKnownStatus) { Content taggedContent = contentTag.getContent(); - if (taggedContent instanceof AbstractFile) { - final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile)taggedContent); + if (taggedContent instanceof AbstractFile) { + final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile) taggedContent); if (eamArtifact != null) { CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); } From 42a077b3ac44a4e1a880f41d36266c8b9a5f4a17 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 14 May 2020 09:32:00 -0400 Subject: [PATCH 2/6] changed logic to always check for other notable tags on source and act accordingly --- .../eventlisteners/CaseEventListener.java | 188 ++++++++++-------- 1 file changed, 101 insertions(+), 87 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 22642cab6c..507a9e8112 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -209,81 +209,84 @@ final class CaseEventListener implements PropertyChangeListener { } else if (curEventType == Case.Events.CONTENT_TAG_DELETED && event instanceof ContentTagDeletedEvent) { handleTagDeleted((ContentTagDeletedEvent) event); } else { - LOGGER.log(Level.WARNING, + 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)); } } - /** - * When a tag is added, handle whether or not to add/update the central - * repository correlation attribute instance for the file. A correlation - * attribute instance will be created / updated if the tag is notable. - * - * @param tagAddedEvent The event where a tag was added. - */ - private void handleTagAdded(ContentTagAddedEvent tagAddedEvent) { - final ContentTag tagAdded = tagAddedEvent.getAddedTag(); - - if (!isNotableTag(tagAdded)) { + private void handleTagDeleted(ContentTagDeletedEvent evt) { + // ensure tag deleted event has a valid content id + if (evt.getDeletedTagInfo() == null) { + LOGGER.log(Level.SEVERE, + String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); return; } + + try { + // 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; + } + + // then handle the event + handleTagChange(content); + } catch (NoCurrentCaseException | TskCoreException ex) { + LOGGER.log(Level.WARNING, "Error updating non-file object."); + } + } + 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, + String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); + 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(tagAdded.getContent().getId()); + af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(content.getId()); } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.WARNING, "Error updating non-file object"); + LOGGER.log(Level.WARNING, "Error updating non-file object."); } if (af == null) { return; } - - setContentKnownStatus(af, TskData.FileKnown.BAD); - } - - /** - * For deleted tags, set the central repository correlation attribute - * instance file status to unknown if the tag that was deleted was the - * only tag on the file that confers notability. - * - * @param tagDeletedEvent The tag deleted event containing information - * about the tag that is being deleted. - */ - private void handleTagDeleted(ContentTagDeletedEvent tagDeletedEvent) { - if (!isNotableTagName(tagDeletedEvent.getDeletedTagInfo().getName())) { - // If the tag that got removed isn't on the list of central repo tags, do nothing - return; - } - - long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID(); - + try { - // Get the remaining tags on the content object - Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(contentID); + // Get the tags on the content object TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager(); if (hasNotableTag(tagsManager.getContentTagsByContent(content))) { - // There's still at least one bad tag, so leave the known status as is - return; + // if there is a notable tag on the object, set content known status to bad + setContentKnownStatus(af, TskData.FileKnown.BAD); } - - // There are no more bad tags on the object - AbstractFile af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(contentID); - if (af == null) { - LOGGER.log(Level.WARNING, "Error updating non-file object"); - return; + else { + // otherwise, set to unknown + setContentKnownStatus(af, TskData.FileKnown.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. @@ -295,7 +298,6 @@ final class CaseEventListener implements PropertyChangeListener { */ private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) { final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af); - eamArtifact.setComment(""); if (eamArtifact != null) { // send update to Central Repository db @@ -336,43 +338,60 @@ final class CaseEventListener implements PropertyChangeListener { } } - /** - * When a tag is added, handle whether or not to add/update the central - * repository correlation attribute instance for the artifact. A - * correlation attribute instance will be created / updated if the tag - * is notable and the file is not known. - * - * @param tagAddedEvent The event where a tag was added. - */ - private void handleTagAdded(BlackBoardArtifactTagAddedEvent tagAddedEvent) { - final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag(); - - // The added tag isn't flagged as bad in central repo, so do nothing - if (!isNotableTag(tagAdded)) { + private void handleTagDeleted(BlackBoardArtifactTagDeletedEvent evt) { + // ensure tag deleted event has a valid content id + if (evt.getDeletedTagInfo() == null) { + LOGGER.log(Level.SEVERE, + String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); return; } + + 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."); + } + } - if (isKnownFile(tagAdded.getContent())) { + private void handleTagAdded(BlackBoardArtifactTagAddedEvent evt) { + // ensure tag added event has a valid content id + if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null) { + LOGGER.log(Level.SEVERE, + String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); return; } - - setArtifactKnownStatus(tagAdded.getArtifact(), TskData.FileKnown.BAD); + + // then handle the event + handleTagChange(evt.getAddedTag().getContent(), evt.getAddedTag().getArtifact()); } /** - * For deleted tags, set the central repository correlation attribute - * instance file status to unknown if the tag that was deleted was the - * only tag on the file that confers notability. + * 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 tagDeletedEvent The tag deleted event containing information - * about the tag that is begin deleted. + * @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 handleTagDeleted(BlackBoardArtifactTagDeletedEvent tagDeletedEvent) { - if (!isNotableTagName(tagDeletedEvent.getDeletedTagInfo().getName())) { - // If the tag that got removed isn't on the list of central repo tags, do nothing - return; - } - + private void handleTagChange(Content content, BlackboardArtifact bbArtifact) { Case openCase; try { openCase = Case.getCurrentCaseThrows(); @@ -381,26 +400,21 @@ final class CaseEventListener implements PropertyChangeListener { return; } - long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID(); - long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID(); - try { - // Get the remaining tags on the artifact - Content content = openCase.getSleuthkitCase().getContentById(contentID); if (isKnownFile(content)) { return; } - BlackboardArtifact bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(artifactID); TagsManager tagsManager = openCase.getServices().getTagsManager(); List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact); if (hasNotableTag(tags)) { - return; + setArtifactKnownStatus(bbArtifact, TskData.FileKnown.BAD); + } + else { + setArtifactKnownStatus(bbArtifact, TskData.FileKnown.UNKNOWN); } - - 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; } } From 2d3dcc43e8f84bb49430f70f4005f099c78955ef Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 14 May 2020 09:55:23 -0400 Subject: [PATCH 3/6] defensive code --- .../centralrepository/eventlisteners/CaseEventListener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 507a9e8112..cbd136b31c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -374,7 +374,7 @@ final class CaseEventListener implements PropertyChangeListener { private void handleTagAdded(BlackBoardArtifactTagAddedEvent evt) { // ensure tag added event has a valid content id - if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null) { + if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null || evt.getAddedTag().getArtifact() == null) { LOGGER.log(Level.SEVERE, String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); return; @@ -440,7 +440,6 @@ final class CaseEventListener implements PropertyChangeListener { private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) { List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { - eamArtifact.setComment(""); try { dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus); } catch (CentralRepoException ex) { From 7c1d01bc058828c1a7d79ccf8feb75966ab75707 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 14 May 2020 09:57:00 -0400 Subject: [PATCH 4/6] formatting --- .../datamodel/RdbmsCentralRepo.java | 232 +++++++++--------- .../eventlisteners/CaseEventListener.java | 45 ++-- 2 files changed, 135 insertions(+), 142 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index b5e044d6e9..42174a4c65 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -82,7 +82,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { private static final Cache, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder() .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); - + private boolean isCRTypeCacheInitialized; private static final Cache typeCache = CacheBuilder.newBuilder().build(); private static final Cache caseCacheByUUID = CacheBuilder.newBuilder() @@ -105,8 +105,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { static final int DEFAULT_BULK_THRESHHOLD = 1000; private static final int QUERY_STR_MAX_LEN = 1000; - - + /** * Connect to the DB and initialize it. * @@ -137,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. * @@ -223,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; } @@ -1017,27 +1017,26 @@ abstract class RdbmsCentralRepo implements CentralRepository { // @@@ We should cache the case and data source IDs in memory String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType()); - + String sql; // _instance table for accounts have an additional account_id column if (artifactHasAnAccount) { - sql = "INSERT INTO " - + tableName - + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " - + getConflictClause(); - } - else { - sql = "INSERT INTO " - + tableName - + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " - + "VALUES (?, ?, ?, ?, ?, ?, ?) " - + getConflictClause(); + sql = "INSERT INTO " + + tableName + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); + } else { + sql = "INSERT INTO " + + tableName + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); } try (Connection conn = connect(); - PreparedStatement preparedStatement = conn.prepareStatement(sql);) { - + PreparedStatement preparedStatement = conn.prepareStatement(sql);) { + if (!eamArtifact.getCorrelationValue().isEmpty()) { preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID()); preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID()); @@ -1051,7 +1050,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { preparedStatement.setString(6, eamArtifact.getComment()); } preparedStatement.setLong(7, eamArtifact.getFileObjectId()); - + // set in the accountId only for artifacts that represent accounts if (artifactHasAnAccount) { if (eamArtifact.getAccountId() >= 0) { @@ -1066,21 +1065,21 @@ abstract class RdbmsCentralRepo implements CentralRepository { } catch (SQLException ex) { throw new CentralRepoException("Error inserting new artifact into artifacts table.", ex); // NON-NLS - } + } } - /** - * Gets the Central Repo account for the given account type and account ID. - * Create a new account first, if one doesn't exist - * - * @param accountType account type - * @param accountUniqueID unique account identifier - * - * @return A matching account, either existing or newly created. - * - * @throws TskCoreException exception thrown if a critical error occurs - * within TSK core - */ + /** + * Gets the Central Repo account for the given account type and account ID. + * Create a new account first, if one doesn't exist + * + * @param accountType account type + * @param accountUniqueID unique account identifier + * + * @return A matching account, either existing or newly created. + * + * @throws TskCoreException exception thrown if a critical error occurs + * within TSK core + */ @Override public CentralRepoAccount getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { // Get the account fom the accounts table @@ -1106,56 +1105,53 @@ abstract class RdbmsCentralRepo implements CentralRepository { return account; } - @Override public CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException { try { return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName)); } catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) { - throw new CentralRepoException("Error looking up CR account type in cache.", ex); - } + throw new CentralRepoException("Error looking up CR account type in cache.", ex); + } } - - @Override public Collection getAllAccountTypes() throws CentralRepoException { - - Collection accountTypes = new ArrayList<>(); - - String sql = "SELECT * FROM account_types"; - try ( Connection conn = connect(); - PreparedStatement preparedStatement = conn.prepareStatement(sql);) { - + Collection accountTypes = new ArrayList<>(); + + String sql = "SELECT * FROM account_types"; + 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")); CentralRepoAccountType crAccountType = new CentralRepoAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id")); - + accountTypes.add(crAccountType); - } + } } } catch (SQLException ex) { throw new CentralRepoException("Error getting account types from central repository.", ex); // NON-NLS - } + } return accountTypes; } - + /** * Gets the CR account type for the specified type name. - * + * * @param accountTypeName account type name to look for + * * @return CR account type - * - * @throws CentralRepoException + * + * @throws CentralRepoException */ private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException { String sql = "SELECT * FROM account_types WHERE type_name = ?"; - try ( Connection conn = connect(); - PreparedStatement preparedStatement = conn.prepareStatement(sql);) { + try (Connection conn = connect(); + PreparedStatement preparedStatement = conn.prepareStatement(sql);) { preparedStatement.setString(1, accountTypeName); try (ResultSet resultSet = preparedStatement.executeQuery();) { @@ -1170,24 +1166,27 @@ abstract class RdbmsCentralRepo implements CentralRepository { } } catch (SQLException ex) { throw new CentralRepoException("Error getting correlation type by id.", ex); // NON-NLS - } + } } - + /** - * 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. - * - * @param crAccountType account type to look for + * 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. + * + * @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. - * - * @throws CentralRepoException + * + * @return CentralRepoAccount for the give type/id. May return null if not + * found. + * + * @throws CentralRepoException */ private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { - + CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID)); if (crAccount == null) { crAccount = getCRAccountFromDb(crAccountType, accountUniqueID); @@ -1195,30 +1194,29 @@ abstract class RdbmsCentralRepo implements CentralRepository { accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount); } } - + 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 accountType account type * @param accountUniqueID unique account identifier * * @return Account, returns NULL is no matching account found * * @throws TskCoreException exception thrown if a critical error occurs - * within TSK core + * within TSK core */ private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { CentralRepoAccount account = null; String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?"; - try ( Connection connection = connect(); - PreparedStatement preparedStatement = connection.prepareStatement(sql);) { + try (Connection connection = connect(); + PreparedStatement preparedStatement = connection.prepareStatement(sql);) { preparedStatement.setInt(1, crAccountType.getAccountTypeId()); preparedStatement.setString(2, accountUniqueID); @@ -1234,8 +1232,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { return account; } - - + private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { if (eamArtifact == null) { throw new CentralRepoException("CorrelationAttribute is null"); @@ -1576,7 +1573,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { synchronized (bulkArtifacts) { if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) { - bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()), new ArrayList<>()); + bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()), new ArrayList<>()); } bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact); bulkArtifactsCount++; @@ -2001,11 +1998,10 @@ abstract class RdbmsCentralRepo implements CentralRepository { + "AND file_path=?"; String sqlUpdate - = "UPDATE " - + tableName - + " SET known_status=? WHERE id=?"; - - + = "UPDATE " + + tableName + + " SET known_status=? WHERE id=?"; + try { preparedQuery = conn.prepareStatement(sqlQuery); preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID()); @@ -2325,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) { @@ -2337,8 +2332,6 @@ abstract class RdbmsCentralRepo implements CentralRepository { CentralRepoDbUtil.closeConnection(conn); } } - - /** * Check if the given value is in a specific reference set @@ -2509,7 +2502,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { CentralRepoDbUtil.closeConnection(conn); } } - + /** * Process a SELECT query * @@ -2547,7 +2540,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { CentralRepoDbUtil.closeResultSet(resultSet); CentralRepoDbUtil.closeConnection(conn); } - } + } @Override public void executeInsertSQL(String insertClause) throws CentralRepoException { @@ -2590,7 +2583,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { throw new CentralRepoException(String.format("Error running SQL %s, exception = %s", selectSQL, ex.getMessage()), ex); } } - + @Override public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg) throws CentralRepoException { if (eamOrg == null) { @@ -2730,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. + * inserting the user in the examiners table. */ - @Override public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException { @@ -2763,7 +2757,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { default: throw new CentralRepoException(String.format("Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform())); //NON-NLS } - statement.execute(insertSQL); + statement.execute(insertSQL); // Query the table again to get the row for the user try (ResultSet resultSet2 = statement.executeQuery(querySQL)) { @@ -2783,7 +2777,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { throw new CentralRepoException("Error getting examiner for name = " + examinerLoginName, ex); } } - + /** * Update an existing organization. * @@ -3178,7 +3172,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { typeId = newCorrelationTypeKnownId(newType); } - synchronized(typeCache) { + synchronized (typeCache) { typeCache.put(newType.getId(), newType); } return typeId; @@ -3395,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) { @@ -3419,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) { @@ -3430,7 +3424,6 @@ abstract class RdbmsCentralRepo implements CentralRepository { } } - /** * Get the EamArtifact.Type that has the given Type.Id from the central repo * @@ -3469,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(); - PreparedStatement preparedStatement = conn.prepareStatement(sql); - ResultSet resultSet = preparedStatement.executeQuery();) { - synchronized(typeCache) { + String sql = "SELECT * FROM correlation_types"; + try (Connection conn = connect(); + PreparedStatement preparedStatement = conn.prepareStatement(sql); + ResultSet resultSet = preparedStatement.executeQuery();) { + + synchronized (typeCache) { while (resultSet.next()) { CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet); typeCache.put(aType.getId(), aType); @@ -3495,9 +3489,9 @@ abstract class RdbmsCentralRepo implements CentralRepository { } } catch (SQLException ex) { throw new CentralRepoException("Error getting correlation types.", ex); // NON-NLS - } + } } - + /** * Convert a ResultSet to a EamCase object * @@ -3655,13 +3649,13 @@ abstract class RdbmsCentralRepo implements CentralRepository { case POSTGRESQL: return "INSERT " + sql + " ON CONFLICT DO NOTHING"; //NON-NLS case SQLITE: - return "INSERT OR IGNORE " + sql; - + return "INSERT OR IGNORE " + sql; + default: throw new CentralRepoException("Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform()); } } - + /** * Determine if a specific column already exists in a specific table * @@ -3774,7 +3768,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { */ if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 2)) < 0) { final String addIntegerColumnTemplate = "ALTER TABLE %s ADD COLUMN %s INTEGER;"; //NON-NLS - + final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform); final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(); final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(); @@ -3794,7 +3788,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { default: throw new CentralRepoException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name())); } - + final String dataSourcesTableName = "data_sources"; final String dataSourceObjectIdColumnName = "datasource_obj_id"; if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) { @@ -3959,7 +3953,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { // Upgrade to 1.4 (new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn); - + // Upgrade to 1.5 (new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index cbd136b31c..44e19ca11c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -90,7 +90,7 @@ final class CaseEventListener implements PropertyChangeListener { if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) { return; } - + CentralRepository dbManager; try { dbManager = CentralRepository.getInstance(); @@ -222,16 +222,16 @@ final class CaseEventListener implements PropertyChangeListener { String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); return; } - + try { // 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())); + String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID())); return; } - + // then handle the event handleTagChange(content); } catch (NoCurrentCaseException | TskCoreException ex) { @@ -246,14 +246,15 @@ final class CaseEventListener implements PropertyChangeListener { String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); 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. + * 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. */ @@ -268,7 +269,7 @@ final class CaseEventListener implements PropertyChangeListener { if (af == null) { return; } - + try { // Get the tags on the content object TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager(); @@ -276,8 +277,7 @@ final class CaseEventListener implements PropertyChangeListener { 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 { + } else { // otherwise, set to unknown setContentKnownStatus(af, TskData.FileKnown.UNKNOWN); } @@ -286,7 +286,6 @@ final class CaseEventListener implements PropertyChangeListener { } } - /** * Sets the known status for the correlation attribute instance for the * given abstract file. @@ -345,26 +344,26 @@ final class CaseEventListener implements PropertyChangeListener { String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); return; } - + 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())); + 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())); + 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) { @@ -379,16 +378,17 @@ final class CaseEventListener implements PropertyChangeListener { String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); 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. + * 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 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) { @@ -409,8 +409,7 @@ final class CaseEventListener implements PropertyChangeListener { List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact); if (hasNotableTag(tags)) { setArtifactKnownStatus(bbArtifact, TskData.FileKnown.BAD); - } - else { + } else { setArtifactKnownStatus(bbArtifact, TskData.FileKnown.UNKNOWN); } } catch (TskCoreException ex) { From 1ea70b7dab165182a533a0c8054aca2f59b07bf5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 15 May 2020 14:53:29 -0400 Subject: [PATCH 5/6] logging updates --- .../eventlisteners/CaseEventListener.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 44e19ca11c..e201f6b642 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -218,8 +218,7 @@ final class CaseEventListener implements PropertyChangeListener { private void handleTagDeleted(ContentTagDeletedEvent evt) { // ensure tag deleted event has a valid content id if (evt.getDeletedTagInfo() == null) { - LOGGER.log(Level.SEVERE, - String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); + LOGGER.log(Level.SEVERE, "ContentTagDeletedEvent did not have valid content to provide a content id."); return; } @@ -235,15 +234,15 @@ final class CaseEventListener implements PropertyChangeListener { // then handle the event handleTagChange(content); } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.WARNING, "Error updating non-file object."); + Long contentID = (evt != null && evt.getDeletedTagInfo() != null) ? evt.getDeletedTagInfo().getContentID() : null; + LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, 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, - String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); + LOGGER.log(Level.SEVERE, "ContentTagAddedEvent did not have valid content to provide a content id."); return; } @@ -263,7 +262,8 @@ final class CaseEventListener implements PropertyChangeListener { try { af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(content.getId()); } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.WARNING, "Error updating non-file object."); + Long contentID = (content != null) ? content.getId() : null; + LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, ex); } if (af == null) { @@ -340,8 +340,7 @@ final class CaseEventListener implements PropertyChangeListener { private void handleTagDeleted(BlackBoardArtifactTagDeletedEvent evt) { // ensure tag deleted event has a valid content id if (evt.getDeletedTagInfo() == null) { - LOGGER.log(Level.SEVERE, - String.format("ContentTagDeletedEvent %s did not have valid content to provide a content id.", evt)); + LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagDeletedEvent did not have valid content to provide a content id."); return; } @@ -367,15 +366,14 @@ final class CaseEventListener implements PropertyChangeListener { // then handle the event handleTagChange(content, bbArtifact); } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.WARNING, "Error updating non-file object."); + 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, - String.format("ContentTagAddedEvent %s did not have valid content to provide a content id.", evt)); + LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagAddedEvent did not have valid content to provide a content id."); return; } From a37080c9b260368a4fc8f45ba7965b921768823e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 18 May 2020 08:42:37 -0400 Subject: [PATCH 6/6] logging update --- .../centralrepository/eventlisteners/CaseEventListener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index e201f6b642..94a22492c1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -234,8 +234,7 @@ final class CaseEventListener implements PropertyChangeListener { // then handle the event handleTagChange(content); } catch (NoCurrentCaseException | TskCoreException ex) { - Long contentID = (evt != null && evt.getDeletedTagInfo() != null) ? evt.getDeletedTagInfo().getContentID() : null; - LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, ex); + LOGGER.log(Level.WARNING, "Error updating non-file object: " + evt.getDeletedTagInfo().getContentID(), ex); } }