From 2ec73212d45bf6b158e7ad13f7c010081e5e7d11 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 12 Sep 2017 09:57:39 -0400 Subject: [PATCH] Known bad can be automatically added when setting a tag to BAD --- .../datamodel/AbstractSqlEamDb.java | 45 +++++++++++- .../datamodel/EamArtifactUtil.java | 70 +++++++++++++++++++ .../centralrepository/datamodel/EamDb.java | 9 +++ .../datamodel/SqliteEamDb.java | 19 ++++- .../eventlisteners/CaseEventListener.java | 16 ++++- .../optionspanel/ManageTagsDialog.java | 45 ++++++++++++ 6 files changed, 198 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 475f6459d5..4792616d88 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -33,12 +33,13 @@ import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.logging.Level; -import javafx.animation.KeyValue; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.BlackboardArtifactTag; +import org.sleuthkit.datamodel.TagName; +import org.sleuthkit.datamodel.ContentTag; /** * @@ -1063,7 +1064,8 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Sets an eamArtifact instance as knownStatus = "Bad". If eamArtifact - * exists, it is updated. If eamArtifact does not exist nothing happens + * exists, it is updated. If eamArtifact does not exist it is added + * with knownStatus = "Bad" * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. */ @@ -1149,6 +1151,43 @@ public abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } + + /** + * Set knownBad status for all files/artifacts in the given case that + * are tagged with the given tag name. + * Files/artifacts that are not already in the database will be added. + * @param tagName The name of the tag to search for + * @param curCase The case to search in + */ + @Override + public void setArtifactsKnownBadByTag(String tagNameString, Case curCase) throws EamDbException{ + try{ + TagName tagName = curCase.getServices().getTagsManager().getDisplayNamesToTagNamesMap().get(tagNameString); + + // First find any matching artifacts + List artifactTags = curCase.getSleuthkitCase().getBlackboardArtifactTagsByTagName(tagName); + System.out.println("\n####### There are " + artifactTags.size() + " matching artifact tags for tag " + tagNameString); + + for(BlackboardArtifactTag bbTag:artifactTags){ + List convertedArtifacts = EamArtifactUtil.fromBlackboardArtifact(bbTag.getArtifact(), true, getCorrelationTypes(), true); + for (EamArtifact eamArtifact : convertedArtifacts) { + setArtifactInstanceKnownBad(eamArtifact); + } + } + + // Now search for files + List fileTags = curCase.getSleuthkitCase().getContentTagsByTagName(tagName); + System.out.println("\n####### There are " + fileTags.size() + " matching file tags for tag " + tagNameString); + for(ContentTag contentTag:fileTags){ + final EamArtifact eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(), + TskData.FileKnown.BAD, ""); + setArtifactInstanceKnownBad(eamArtifact); + } + } catch (Exception ex){ + // fix fix + } + + } /** * Gets list of matching eamArtifact instances that have knownStatus = diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index a582418911..670067ac0a 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskDataException; @@ -192,4 +193,73 @@ public class EamArtifactUtil { return null; } } + + /** + * Create an EamArtifact from the given Content. + * Will return null if an artifact can not be created. Does not + * add the artifact to the database. + * + * @param content The content object + * @param knownStatus Unknown, known bad, or known + * @param comment The comment for the new artifact (generally used for a tag comment) + * @return The new EamArtifact or null if creation failed + */ + public static EamArtifact getEamArtifactFromContent(Content content, TskData.FileKnown knownStatus, String comment){ + + if(! (content instanceof AbstractFile)){ + return null; + } + + final AbstractFile af = (AbstractFile) content; + + if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) + || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) + || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) + || (af.getKnown() == TskData.FileKnown.KNOWN) + || (af.isDir() == true) + || (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) { + return null; + } + + String dsName; + try { + dsName = af.getDataSource().getName(); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error, unable to get name of data source from abstract file.", ex); + return null; + } + + // We need a hash to make the artifact + String md5 = af.getMd5Hash(); + if (md5 == null || md5.isEmpty()) { + return null; + } + + String deviceId; + try { + deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId(); + } catch (TskCoreException | TskDataException ex) { + LOGGER.log(Level.SEVERE, "Error, failed to get deviceID or data source from current case.", ex); + return null; + } + + EamArtifact eamArtifact; + try { + EamArtifact.Type filesType = EamDb.getInstance().getCorrelationTypeById(EamArtifact.FILES_TYPE_ID); + eamArtifact = new EamArtifact(filesType, af.getMd5Hash()); + EamArtifactInstance cei = new EamArtifactInstance( + new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()), + new EamDataSource(deviceId, dsName), + af.getParentPath() + af.getName(), + comment, + TskData.FileKnown.BAD, + EamArtifactInstance.GlobalStatus.LOCAL + ); + eamArtifact.addInstance(cei); + return eamArtifact; + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "Error, unable to get FILES correlation type.", ex); + return null; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 4d89314ffe..f6df682910 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -326,6 +326,15 @@ public interface EamDb { */ void setArtifactInstanceKnownBad(EamArtifact eamArtifact) throws EamDbException; + /** + * Set knownBad status for all files/artifacts in the given case that + * are tagged with the given tag name. + * Files/artifacts that are not already in the database will be added. + * @param tagName The name of the tag to search for + * @param curCase The case to search in + */ + void setArtifactsKnownBadByTag(String tagNameString, Case curCase) throws EamDbException; + /** * Gets list of matching eamArtifact instances that have knownStatus = * "Bad". diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 01d2083af4..4d96c22910 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -599,7 +599,24 @@ public class SqliteEamDb extends AbstractSqlEamDb { } finally { releaseExclusiveLock(); } - } + } + + /** + * Set knownBad status for all files/artifacts in the given case that + * are tagged with the given tag name. + * Files/artifacts that are not already in the database will be added. + * @param tagName The name of the tag to search for + * @param curCase The case to search in + */ + @Override + public void setArtifactsKnownBadByTag(String tagNameString, Case curCase) throws EamDbException{ + try{ + acquireExclusiveLock(); + super.setArtifactsKnownBadByTag(tagNameString, curCase); + } finally { + releaseExclusiveLock(); + } + } /** * Gets list of matching eamArtifact instances that have knownStatus = diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 7c4201012f..8a07143e68 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -75,9 +75,21 @@ public class CaseEventListener implements PropertyChangeListener { final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) evt; final ContentTag tagAdded = tagAddedEvent.getAddedTag(); // TODO: detect failed cast and break if so. - final AbstractFile af = (AbstractFile) tagAdded.getContent(); + //final AbstractFile af = (AbstractFile) tagAdded.getContent(); final TagName tagName = tagAdded.getName(); + + if (dbManager.getBadTags().contains(tagName.getDisplayName())) { + final EamArtifact eamArtifact = EamArtifactUtil.getEamArtifactFromContent(tagAdded.getContent(), + TskData.FileKnown.BAD, tagAdded.getComment()); + // send update to Central Repository db + Runnable r = new BadFileTagRunner(eamArtifact); + // TODO: send r into a thread pool instead + Thread t = new Thread(r); + t.start(); + } + + /* if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) @@ -129,7 +141,7 @@ public class CaseEventListener implements PropertyChangeListener { } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error, unable to get FILES correlation type during CONTENT_TAG_ADDED event.", ex); } - } + }*/ } // CONTENT_TAG_ADDED break; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageTagsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageTagsDialog.java index a5c0b87b1b..b42be9bd06 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageTagsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageTagsDialog.java @@ -27,8 +27,12 @@ import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JFrame; import javax.swing.table.DefaultTableModel; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.JOptionPane; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -92,6 +96,8 @@ final class ManageTagsDialog extends javax.swing.JDialog { boolean enabled = badTags.contains(tagName); model.addRow(new Object[]{tagName, enabled}); } + CheckBoxModelListener listener = new CheckBoxModelListener(); + model.addTableModelListener(listener); } private void display() { @@ -230,6 +236,45 @@ final class ManageTagsDialog extends javax.swing.JDialog { } return true; } + + public class CheckBoxModelListener implements TableModelListener { + + @Override + public void tableChanged(TableModelEvent e) { + int row = e.getFirstRow(); + int column = e.getColumn(); + if (column == 1) { + DefaultTableModel model = (DefaultTableModel) e.getSource(); + String columnName = model.getColumnName(column); + String tagName = (String) model.getValueAt(row, 0); + Boolean checked = (Boolean) model.getValueAt(row, column); + if (checked) { + System.out.println(tagName + " " + columnName + ": " + true); + + + if(Case.isCaseOpen()){ + int dialogButton = JOptionPane.YES_NO_OPTION; + // The actual idea: Flag any files/artifacts that are already in the central repo and that match + // this thing? Or maye not that first part. However it already works + int dialogResult = JOptionPane.showConfirmDialog (null, "Tag the things??","Warning",dialogButton); + if(dialogResult == JOptionPane.YES_OPTION){ + try{ + EamDb.getInstance().setArtifactsKnownBadByTag(tagName, Case.getCurrentCase()); + } catch (Exception ex) { // fix fix fix + ex.printStackTrace(); + } + } + } else { + System.out.println(" No case open"); + } + + + } else { + System.out.println(tagName + " " + columnName + ": " + false); + } + } + } + } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup buttonGroup1;