diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java index 85f0fcd6de..f1f0b5ea91 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java @@ -25,8 +25,8 @@ import java.nio.file.Files; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -89,7 +89,7 @@ public final class OtherOccurrences { logger.log(Level.INFO, String.format("Unable to check create CorrelationAttribtueInstance for osAccount %s.", osAccountAddr.get()), ex); } } - return new ArrayList<>(); + return Collections.emptyList(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index ffd9c96399..bc934b0926 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -86,7 +87,7 @@ public class CorrelationAttributeUtil { if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { - return new ArrayList<>(); + return Collections.emptyList(); } return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); } @@ -109,7 +110,7 @@ public class CorrelationAttributeUtil { } public static List makeCorrAttrsToSave(AnalysisResult file) { - return new ArrayList<>(); + return Collections.emptyList(); } public static List makeCorrAttrsToSave(OsAccountInstance osAccountInstance) { @@ -354,7 +355,7 @@ public class CorrelationAttributeUtil { /* * Normalize the phone number. */ - List corrAttrInstances = new ArrayList<>(); + List corrAttrInstances = Collections.emptyList(); if (value != null && CorrelationAttributeNormalizer.isValidPhoneNumber(value)) { value = CorrelationAttributeNormalizer.normalizePhone(value); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java index ed153a50cb..44924a0a30 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java @@ -137,7 +137,7 @@ public class AnnotationUtils { * @return The pair of artifact (or null if not present) and content (either * artifact parent content, the node content, or null). */ - private static Pair getDisplayContent(Node node) { + static DisplayTskItems getDisplayContent(Node node) { BlackboardArtifactItem artItem = node.getLookup().lookup(BlackboardArtifactItem.class); BlackboardArtifact artifact = artItem == null ? null : artItem.getTskContent(); @@ -145,7 +145,7 @@ public class AnnotationUtils { ? artItem.getSourceContent() : node.getLookup().lookup(AbstractFile.class); - return Pair.of(artifact, content); + return new DisplayTskItems(artifact, content); } /** @@ -156,7 +156,7 @@ public class AnnotationUtils { * @return True if the node is supported. */ public static boolean isSupported(Node node) { - return getDisplayContent(node).getRight() != null; + return getDisplayContent(node).getContent() != null; } /** @@ -172,9 +172,9 @@ public class AnnotationUtils { Document html = Jsoup.parse(EMPTY_HTML); Element body = html.getElementsByTag("body").first(); - Pair displayPair = getDisplayContent(node); - BlackboardArtifact artifact = displayPair.getLeft(); - Content srcContent = displayPair.getRight(); + DisplayTskItems displayItems = getDisplayContent(node); + BlackboardArtifact artifact = displayItems.getArtifact(); + Content srcContent = displayItems.getContent(); boolean somethingWasRendered = false; if (artifact != null) { @@ -686,4 +686,39 @@ public class AnnotationUtils { } } + /** + * The TSK items that are being displayed as deciphered from the netbeans + * node. + */ + static class DisplayTskItems { + + private final BlackboardArtifact artifact; + private final Content content; + + /** + * Main constructor. + * + * @param artifact The artifact being displayed or null. + * @param content The parent content or source file being displayed or + * null. + */ + DisplayTskItems(BlackboardArtifact artifact, Content content) { + this.artifact = artifact; + this.content = content; + } + + /** + * @return The selected artifact or null if no selected artifact. + */ + BlackboardArtifact getArtifact() { + return artifact; + } + + /** + * @return The parent content or source file being displayed or null. + */ + Content getContent() { + return content; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java index faed21e1b1..c01548026b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java @@ -18,10 +18,16 @@ */ package org.sleuthkit.autopsy.contentviewers.annotations; +import com.google.common.collect.ImmutableSet; import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.EnumSet; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.SwingWorker; +import org.apache.commons.lang3.tuple.Pair; import static org.openide.util.NbBundle.Messages; import org.openide.nodes.Node; @@ -29,8 +35,19 @@ import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.jsoup.nodes.Document; +import org.openide.util.WeakListeners; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent; +import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent; +import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent; +import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; +import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; +import org.sleuthkit.autopsy.contentviewers.annotations.AnnotationUtils.DisplayTskItems; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.contentviewers.utils.ViewerPriority; +import org.sleuthkit.autopsy.ingest.IngestManager; +import org.sleuthkit.autopsy.ingest.ModuleDataEvent; +import org.sleuthkit.datamodel.BlackboardArtifact; /** * Annotations view of file contents. @@ -47,7 +64,75 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName()); - private AnnotationWorker worker; + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( + Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, + Case.Events.CONTENT_TAG_ADDED, + Case.Events.CONTENT_TAG_DELETED, + Case.Events.CR_COMMENT_CHANGED); + + private static final Set INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED); + + private static final Set ARTIFACT_TYPES_OF_INTEREST = ImmutableSet.of( + BlackboardArtifact.Type.TSK_HASHSET_HIT, + BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT + ); + + private final PropertyChangeListener ingestEventListener = (evt) -> { + Long curArtifactId = AnnotationsContentViewer.this.curArtifactId; + Long curContentId = AnnotationsContentViewer.this.curContentId; + + if (curArtifactId == null && curContentId == null) { + return; + } + + // if it is a module data event + if (IngestManager.IngestModuleEvent.DATA_ADDED.toString().equals(evt.getPropertyName()) + && evt.getOldValue() instanceof ModuleDataEvent) { + + ModuleDataEvent moduleDataEvent = (ModuleDataEvent) evt.getOldValue(); + + // if an artifact is relevant, refresh + if (ARTIFACT_TYPES_OF_INTEREST.contains(moduleDataEvent.getBlackboardArtifactType())) { + for (BlackboardArtifact artifact : moduleDataEvent.getArtifacts()) { + if ((curArtifactId != null && artifact.getArtifactID() == curArtifactId) + || (curContentId != null && artifact.getObjectID() == curContentId)) { + refresh(); + return; + } + } + } + } + }; + + private final PropertyChangeListener weakIngestEventListener = WeakListeners.propertyChange(ingestEventListener, null); + + private final PropertyChangeListener caseEventListener = (evt) -> { + Long curArtifactId = AnnotationsContentViewer.this.curArtifactId; + Long curContentId = AnnotationsContentViewer.this.curContentId; + + if (curArtifactId == null && curContentId == null) { + return; + } + + Pair artifactContentId = getIdsFromEvent(evt); + Long artifactId = artifactContentId.getLeft(); + Long contentId = artifactContentId.getRight(); + + // if there is a match of content id or artifact id and the event, refresh + if ((curArtifactId != null && curArtifactId.equals(artifactId)) || (curContentId != null && curContentId.equals(contentId))) { + refresh(); + } + }; + + private final PropertyChangeListener weakCaseEventListener = WeakListeners.propertyChange(caseEventListener, null); + + private final Object updateLock = new Object(); + + private AnnotationWorker worker = null; + private Node node; + private Long curArtifactId; + private Long curContentId; /** * Creates an instance of AnnotationsContentViewer. @@ -55,23 +140,138 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data public AnnotationsContentViewer() { initComponents(); ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel); + registerListeners(); + } + + /** + * Registers case event and ingest event listeners. + */ + private void registerListeners() { + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakCaseEventListener); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakIngestEventListener); + } + + @Override + protected void finalize() throws Throwable { + unregisterListeners(); + } + + /** + * Unregisters case event and ingest event listeners. + */ + private void unregisterListeners() { + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakCaseEventListener); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakIngestEventListener); } @Override public void setNode(Node node) { - resetComponent(); + this.node = node; + DisplayTskItems displayItems = AnnotationUtils.getDisplayContent(node); + this.curArtifactId = displayItems.getArtifact() == null ? null : displayItems.getArtifact().getArtifactID(); + this.curContentId = displayItems.getContent() == null ? null : displayItems.getContent().getId(); + updateData(this.node, true); + } - if (worker != null) { - worker.cancel(true); - worker = null; + /** + * Returns a pair of the artifact id (or null) and the content id (or null) + * for the case event. + * + * @param evt The case event. + * + * @return A pair of the artifact id (or null) and the content id (or null) + * for the case event. + */ + private static Pair getIdsFromEvent(PropertyChangeEvent evt) { + Case.Events eventType = null; + try { + eventType = Case.Events.valueOf(evt.getPropertyName()); + } catch (IllegalArgumentException ex) { + logger.log(Level.SEVERE, "Unknown event type: " + evt.getPropertyName(), ex); + return Pair.of(null, null); } + Long artifactId = null; + Long contentId = null; + + switch (eventType) { + case BLACKBOARD_ARTIFACT_TAG_ADDED: + if (evt instanceof BlackBoardArtifactTagAddedEvent) { + BlackboardArtifact art = ((BlackBoardArtifactTagAddedEvent) evt).getAddedTag().getArtifact(); + artifactId = art.getArtifactID(); + contentId = art.getObjectID(); + } + break; + case BLACKBOARD_ARTIFACT_TAG_DELETED: + if (evt instanceof BlackBoardArtifactTagDeletedEvent) { + artifactId = ((BlackBoardArtifactTagDeletedEvent) evt).getDeletedTagInfo().getArtifactID(); + contentId = ((BlackBoardArtifactTagDeletedEvent) evt).getDeletedTagInfo().getContentID(); + } + break; + case CONTENT_TAG_ADDED: + if (evt instanceof ContentTagAddedEvent) { + contentId = ((ContentTagAddedEvent) evt).getAddedTag().getContent().getId(); + } + break; + case CONTENT_TAG_DELETED: + if (evt instanceof ContentTagDeletedEvent) { + contentId = ((ContentTagDeletedEvent) evt).getDeletedTagInfo().getContentID(); + } + break; + case CR_COMMENT_CHANGED: + if (evt instanceof CommentChangedEvent) { + long commentObjId = ((CommentChangedEvent) evt).getContentID(); + artifactId = commentObjId; + contentId = commentObjId; + } + break; + default: + break; + }; + + return Pair.of(artifactId, contentId); + } + + /** + * Refreshes the data displayed. + */ + private void refresh() { + if (this.isVisible()) { + updateData(this.node, false); + } + } + + /** + * Updates data displayed in the viewer. + * + * @param node The node to use for data. + * @param forceReset If true, forces a reset cancelling the previous worker + * if one exists and clearing data in the component. If + * false, only submits a worker if no previous worker is + * running. + */ + private void updateData(Node node, boolean forceReset) { if (node == null) { return; } - worker = new AnnotationWorker(node); - worker.execute(); + if (forceReset) { + resetComponent(); + } + + synchronized (updateLock) { + if (worker != null) { + if (forceReset) { + worker.cancel(true); + worker = null; + } else { + return; + } + } + + worker = new AnnotationWorker(node, forceReset); + worker.execute(); + } } /** @@ -142,6 +342,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data @Override public void resetComponent() { textPanel.setText(""); + } /** @@ -151,9 +352,18 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data private class AnnotationWorker extends SwingWorker { private final Node node; + private final boolean resetCaretPosition; - AnnotationWorker(Node node) { + /** + * Main constructor. + * + * @param node The node for which data will be fetched. + * @param resetCaretPosition Whether or not to reset the caret position + * when finished. + */ + AnnotationWorker(Node node, boolean resetCaretPosition) { this.node = node; + this.resetCaretPosition = resetCaretPosition; } @Override @@ -173,17 +383,25 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data @Override public void done() { - if (isCancelled()) { - return; + if (!isCancelled()) { + try { + String text = get(); + ContentViewerHtmlStyles.setStyles(textPanel); + textPanel.setText(text); + + if (resetCaretPosition) { + textPanel.setCaretPosition(0); + } + + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Failed to get annotation information for node", ex); + } } - try { - String text = get(); - ContentViewerHtmlStyles.setStyles(textPanel); - textPanel.setText(text); - textPanel.setCaretPosition(0); - } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, "Failed to get annotation information for node", ex); + synchronized (updateLock) { + if (worker == this) { + worker = null; + } } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java index 9748c3b747..9a4d9e8c22 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java @@ -23,13 +23,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; /** - * An super class for an Autopsy Data Model item class with an underlying - * BlackboardArtifact Sleuth Kit Data Model object, i.e., a DataArtifact or an - * AnalysisResult. + * An abstract super class for an Autopsy Data Model item class with an + * underlying BlackboardArtifact Sleuth Kit Data Model object, i.e., a + * DataArtifact or an AnalysisResult. * - * @param The concrete BlackboardArtifact class type. + * @param The concrete BlackboardArtifact sub class type. */ -public class BlackboardArtifactItem extends TskContentItem { +public abstract class BlackboardArtifactItem extends TskContentItem { private final Content sourceContent; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index d39341dc68..2922996c0e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -404,10 +404,8 @@ public class BlackboardArtifactNode extends AbstractContentNode artifactItem; if (artifact instanceof AnalysisResult) { artifactItem = new AnalysisResultItem((AnalysisResult) artifact, content); - } else if (artifact instanceof DataArtifact) { - artifactItem = new DataArtifactItem((DataArtifact) artifact, content); } else { - artifactItem = new BlackboardArtifactItem<>(artifact, content); + artifactItem = new DataArtifactItem((DataArtifact) artifact, content); } /* diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index a7a4e5870f..06ca641cf7 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -66,7 +66,7 @@ GeolocationPanel_onNoCrIngest_message=No results will be shown because the GPX P GeolocationPanel_unknownRow_title=Unknown PastCasesPanel_caseColumn_title=Case PastCasesPanel_countColumn_title=Count -PastCasesPanel_notableFileTable_tabName=Cases with Common Notable +PastCasesPanel_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest PastCasesPanel_onNoCrIngest_message=No results will be shown because the Central Repository module was not run. PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices RecentFilesPanel_attachmentsTable_tabName=Recent Attachments @@ -75,7 +75,7 @@ RecentFilesPanel_col_header_domain=Domain RecentFilesPanel_col_header_path=Path RecentFilesPanel_col_header_sender=Sender RecentFilesPanel_docsTable_tabName=Recently Opened Documents -RecentFilesPanel_downloadsTable_tabName=Recently Downloads +RecentFilesPanel_downloadsTable_tabName=Recent Downloads RecentFilesPanel_no_open_documents=No recently open documents found. SizeRepresentationUtil_units_bytes=bytes SizeRepresentationUtil_units_gigabytes=GB diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/PastCasesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/PastCasesPanel.java index 08679169d3..f4b4d6e956 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/PastCasesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/PastCasesPanel.java @@ -41,7 +41,7 @@ import org.sleuthkit.datamodel.DataSource; "PastCasesPanel_caseColumn_title=Case", "PastCasesPanel_countColumn_title=Count", "PastCasesPanel_onNoCrIngest_message=No results will be shown because the Central Repository module was not run.", - "PastCasesPanel_notableFileTable_tabName=Cases with Common Notable", + "PastCasesPanel_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest", "PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices",}) public class PastCasesPanel extends BaseDataSourceSummaryPanel { diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java index 0bc09d59ec..4773dae2fc 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java @@ -47,7 +47,7 @@ import org.sleuthkit.datamodel.DataSource; */ @Messages({ "RecentFilesPanel_docsTable_tabName=Recently Opened Documents", - "RecentFilesPanel_downloadsTable_tabName=Recently Downloads", + "RecentFilesPanel_downloadsTable_tabName=Recent Downloads", "RecentFilesPanel_attachmentsTable_tabName=Recent Attachments",}) public final class RecentFilesPanel extends BaseDataSourceSummaryPanel { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java index c258801f70..6a21ef94ba 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.logging.Level; import org.apache.commons.lang.StringUtils; import org.openide.util.Lookup; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.ImageUtils; @@ -194,6 +195,7 @@ class SummaryHelpers { } } + @NbBundle.Messages({"SummaryHelper.documentSummary.unable.to.read=Unable to extract text from file."}) /** * Get the beginning of text from the specified AbstractFile. * @@ -217,7 +219,7 @@ class SummaryHelpers { } catch (IOException ex) { return Bundle.FileSearch_documentSummary_noBytes(); } catch (TextExtractor.InitReaderException ex) { - return Bundle.FileSearch_documentSummary_noPreview(); + return Bundle.SummaryHelper_documentSummary_unable_to_read(); } } diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/Bundle.properties-MERGED index 1767afc028..956adf7e01 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/Bundle.properties-MERGED @@ -54,7 +54,7 @@ ExportIngestHistory_startTimeColumn=Start Time ExportIngestHistory_versionColumn=Module Version ExportPastCases_caseColumn_title=Case ExportPastCases_countColumn_title=Count -ExportPastCases_notableFileTable_tabName=Cases with Common Notable +ExportPastCases_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices ExportRecentFiles_attachmentsTable_tabName=Recent Attachments ExportRecentFiles_col_head_date=Date diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/ExportPastCases.java b/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/ExportPastCases.java index be824477a1..96aefebaff 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/ExportPastCases.java +++ b/Core/src/org/sleuthkit/autopsy/report/modules/datasourcesummaryexport/ExportPastCases.java @@ -37,7 +37,7 @@ import org.sleuthkit.datamodel.DataSource; @Messages({ "ExportPastCases_caseColumn_title=Case", "ExportPastCases_countColumn_title=Count", - "ExportPastCases_notableFileTable_tabName=Cases with Common Notable", + "ExportPastCases_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest", "ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices",}) class ExportPastCases { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index eaac4f12b4..61ddc44921 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -384,6 +384,20 @@ final class RegexQuery implements KeywordSearchQuery { } // Replace all non numeric at the end of the hit. hit = hit.replaceAll("[^0-9]$", ""); + + if (offset > 1) { + /* + * NOTE: our IP and phone number regex patterns look for + * boundary characters immediately before and after + * the keyword hit. After a match, Java pattern + * mather re-starts at the first character not + * matched by the previous match. This basically + * requires two boundary characters to be present + * between each pattern match. To mitigate this we + * are resetting the offest one character back. + */ + offset--; + } } /** diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 5b2b92e49b..3aadf1914b 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -5,6 +5,10 @@ ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for an ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. ChromeCacheExtractor.moduleName=ChromeCacheExtractor +# {0} - module name +# {1} - row number +# {2} - table length +# {3} - cache path ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3} DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card @@ -152,13 +156,19 @@ Firefox.getDlV24.errMsg.errAnalyzeFile={0}: Error while trying to analyze file:{ Firefox.getDlV24.errMsg.errParsingArtifacts={0}: Error parsing {1} Firefox web download artifacts. Progress_Message_Analyze_Registry=Analyzing Registry Files Progress_Message_Analyze_Usage=Data Sources Usage Analysis +# {0} - browserName Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0} +# {0} - browserName Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0} Progress_Message_Chrome_Cache=Chrome Cache +# {0} - browserName Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0} +# {0} - browserName Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0} Progress_Message_Chrome_FormHistory=Chrome Form History +# {0} - browserName Progress_Message_Chrome_History=Chrome History Browser {0} +# {0} - browserName Progress_Message_Chrome_Logins=Chrome Logins Browser {0} Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks Progress_Message_Edge_Cookies=Microsoft Edge Cookies diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java index 42be2d0233..616b13d41f 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java @@ -592,8 +592,13 @@ final class ChromeCacheExtractor { // see if it is cached String fileTableKey = cacheFolderName + cacheFileName; - if (cacheFileName.startsWith("f_") && externalFilesTable.containsKey(fileTableKey)) { - return Optional.of(externalFilesTable.get(fileTableKey)); + + if (cacheFileName != null) { + if (cacheFileName.startsWith("f_") && externalFilesTable.containsKey(fileTableKey)) { + return Optional.of(externalFilesTable.get(fileTableKey)); + } + } else { + return Optional.empty(); } if (fileCopyCache.containsKey(fileTableKey)) { @@ -1306,7 +1311,7 @@ final class ChromeCacheExtractor { private String key; // Key may be found within the entry or may be external - CacheEntry(CacheAddress cacheAdress, FileWrapper cacheFileCopy ) throws TskCoreException { + CacheEntry(CacheAddress cacheAdress, FileWrapper cacheFileCopy ) throws TskCoreException, IngestModuleException { this.selfAddress = cacheAdress; this.cacheFileCopy = cacheFileCopy; @@ -1315,7 +1320,11 @@ final class ChromeCacheExtractor { int entryOffset = DATAFILE_HDR_SIZE + cacheAdress.getStartBlock() * cacheAdress.getBlockSize(); // reposition the buffer to the the correct offset - fileROBuf.position(entryOffset); + if (entryOffset < fileROBuf.capacity()) { + fileROBuf.position(entryOffset); + } else { + throw new IngestModuleException("Position seeked in Buffer to big"); // NON-NLS + } hash = fileROBuf.getInt() & UINT32_MASK; @@ -1364,11 +1373,13 @@ final class ChromeCacheExtractor { if (longKeyAddresses != null) { // Key is stored outside of the entry try { - CacheDataSegment data = new CacheDataSegment(longKeyAddresses, this.keyLen, true); - key = data.getDataString(); + if (longKeyAddresses.getFilename() != null) { + CacheDataSegment data = new CacheDataSegment(longKeyAddresses, this.keyLen, true); + key = data.getDataString(); + } } catch (TskCoreException | IngestModuleException ex) { throw new TskCoreException(String.format("Failed to get external key from address %s", longKeyAddresses)); //NON-NLS - } + } } else { // key stored within entry StringBuilder strBuilder = new StringBuilder(MAX_KEY_LEN); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractZoneIdentifier.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractZoneIdentifier.java index fc59685f9e..5cc6633205 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractZoneIdentifier.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractZoneIdentifier.java @@ -318,7 +318,13 @@ final class ExtractZoneIdentifier extends Extract { */ ZoneIdentifierInfo(AbstractFile zoneFile) throws IOException { fileName = zoneFile.getName(); - properties.load(new ReadContentInputStream(zoneFile)); + // properties.load will throw IllegalArgument if unicode characters are found in the zone file. + try { + properties.load(new ReadContentInputStream(zoneFile)); + } catch (IllegalArgumentException ex) { + String message = String.format("Unable to parse Zone Id for File %s", fileName); //NON-NLS + LOG.log(Level.WARNING, message); + } } /**