Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 7938-OsAccountOCollumn

This commit is contained in:
William Schaefer 2021-09-24 15:14:03 -04:00
commit c63aed98a6
16 changed files with 346 additions and 51 deletions

View File

@ -25,8 +25,8 @@ import java.nio.file.Files;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; 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); logger.log(Level.INFO, String.format("Unable to check create CorrelationAttribtueInstance for osAccount %s.", osAccountAddr.get()), ex);
} }
} }
return new ArrayList<>(); return Collections.emptyList();
} }
/** /**

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -86,7 +87,7 @@ public class CorrelationAttributeUtil {
if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()
|| artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
return new ArrayList<>(); return Collections.emptyList();
} }
return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact);
} }
@ -109,7 +110,7 @@ public class CorrelationAttributeUtil {
} }
public static List<CorrelationAttributeInstance> makeCorrAttrsToSave(AnalysisResult file) { public static List<CorrelationAttributeInstance> makeCorrAttrsToSave(AnalysisResult file) {
return new ArrayList<>(); return Collections.emptyList();
} }
public static List<CorrelationAttributeInstance> makeCorrAttrsToSave(OsAccountInstance osAccountInstance) { public static List<CorrelationAttributeInstance> makeCorrAttrsToSave(OsAccountInstance osAccountInstance) {
@ -354,7 +355,7 @@ public class CorrelationAttributeUtil {
/* /*
* Normalize the phone number. * Normalize the phone number.
*/ */
List<CorrelationAttributeInstance> corrAttrInstances = new ArrayList<>(); List<CorrelationAttributeInstance> corrAttrInstances = Collections.emptyList();
if (value != null if (value != null
&& CorrelationAttributeNormalizer.isValidPhoneNumber(value)) { && CorrelationAttributeNormalizer.isValidPhoneNumber(value)) {
value = CorrelationAttributeNormalizer.normalizePhone(value); value = CorrelationAttributeNormalizer.normalizePhone(value);

View File

@ -137,7 +137,7 @@ public class AnnotationUtils {
* @return The pair of artifact (or null if not present) and content (either * @return The pair of artifact (or null if not present) and content (either
* artifact parent content, the node content, or null). * artifact parent content, the node content, or null).
*/ */
private static Pair<BlackboardArtifact, Content> getDisplayContent(Node node) { static DisplayTskItems getDisplayContent(Node node) {
BlackboardArtifactItem<?> artItem = node.getLookup().lookup(BlackboardArtifactItem.class); BlackboardArtifactItem<?> artItem = node.getLookup().lookup(BlackboardArtifactItem.class);
BlackboardArtifact artifact = artItem == null ? null : artItem.getTskContent(); BlackboardArtifact artifact = artItem == null ? null : artItem.getTskContent();
@ -145,7 +145,7 @@ public class AnnotationUtils {
? artItem.getSourceContent() ? artItem.getSourceContent()
: node.getLookup().lookup(AbstractFile.class); : 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. * @return True if the node is supported.
*/ */
public static boolean isSupported(Node node) { 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); Document html = Jsoup.parse(EMPTY_HTML);
Element body = html.getElementsByTag("body").first(); Element body = html.getElementsByTag("body").first();
Pair<BlackboardArtifact, Content> displayPair = getDisplayContent(node); DisplayTskItems displayItems = getDisplayContent(node);
BlackboardArtifact artifact = displayPair.getLeft(); BlackboardArtifact artifact = displayItems.getArtifact();
Content srcContent = displayPair.getRight(); Content srcContent = displayItems.getContent();
boolean somethingWasRendered = false; boolean somethingWasRendered = false;
if (artifact != null) { 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;
}
}
} }

View File

@ -18,10 +18,16 @@
*/ */
package org.sleuthkit.autopsy.contentviewers.annotations; package org.sleuthkit.autopsy.contentviewers.annotations;
import com.google.common.collect.ImmutableSet;
import java.awt.Component; 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.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.apache.commons.lang3.tuple.Pair;
import static org.openide.util.NbBundle.Messages; import static org.openide.util.NbBundle.Messages;
import org.openide.nodes.Node; 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.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.jsoup.nodes.Document; 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.layout.ContentViewerHtmlStyles;
import org.sleuthkit.autopsy.contentviewers.utils.ViewerPriority; 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. * 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 long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName()); private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
private AnnotationWorker worker; private static final Set<Case.Events> 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<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
private static final Set<BlackboardArtifact.Type> 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<Long, Long> 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. * Creates an instance of AnnotationsContentViewer.
@ -55,23 +140,138 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
public AnnotationsContentViewer() { public AnnotationsContentViewer() {
initComponents(); initComponents();
ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel); 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 @Override
public void setNode(Node node) { 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); * Returns a pair of the artifact id (or null) and the content id (or null)
worker = 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<Long, Long> 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) { if (node == null) {
return; return;
} }
worker = new AnnotationWorker(node); if (forceReset) {
worker.execute(); 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 @Override
public void resetComponent() { public void resetComponent() {
textPanel.setText(""); textPanel.setText("");
} }
/** /**
@ -151,9 +352,18 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
private class AnnotationWorker extends SwingWorker<String, Void> { private class AnnotationWorker extends SwingWorker<String, Void> {
private final Node node; 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.node = node;
this.resetCaretPosition = resetCaretPosition;
} }
@Override @Override
@ -173,17 +383,25 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
@Override @Override
public void done() { public void done() {
if (isCancelled()) { if (!isCancelled()) {
return; 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 { synchronized (updateLock) {
String text = get(); if (worker == this) {
ContentViewerHtmlStyles.setStyles(textPanel); worker = null;
textPanel.setText(text); }
textPanel.setCaretPosition(0);
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, "Failed to get annotation information for node", ex);
} }
} }

View File

@ -23,13 +23,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
/** /**
* An super class for an Autopsy Data Model item class with an underlying * An abstract super class for an Autopsy Data Model item class with an
* BlackboardArtifact Sleuth Kit Data Model object, i.e., a DataArtifact or an * underlying BlackboardArtifact Sleuth Kit Data Model object, i.e., a
* AnalysisResult. * DataArtifact or an AnalysisResult.
* *
* @param <T> The concrete BlackboardArtifact class type. * @param <T> The concrete BlackboardArtifact sub class type.
*/ */
public class BlackboardArtifactItem<T extends BlackboardArtifact> extends TskContentItem<T> { public abstract class BlackboardArtifactItem<T extends BlackboardArtifact> extends TskContentItem<T> {
private final Content sourceContent; private final Content sourceContent;

View File

@ -404,10 +404,8 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
BlackboardArtifactItem<?> artifactItem; BlackboardArtifactItem<?> artifactItem;
if (artifact instanceof AnalysisResult) { if (artifact instanceof AnalysisResult) {
artifactItem = new AnalysisResultItem((AnalysisResult) artifact, content); artifactItem = new AnalysisResultItem((AnalysisResult) artifact, content);
} else if (artifact instanceof DataArtifact) {
artifactItem = new DataArtifactItem((DataArtifact) artifact, content);
} else { } else {
artifactItem = new BlackboardArtifactItem<>(artifact, content); artifactItem = new DataArtifactItem((DataArtifact) artifact, content);
} }
/* /*

View File

@ -66,7 +66,7 @@ GeolocationPanel_onNoCrIngest_message=No results will be shown because the GPX P
GeolocationPanel_unknownRow_title=Unknown GeolocationPanel_unknownRow_title=Unknown
PastCasesPanel_caseColumn_title=Case PastCasesPanel_caseColumn_title=Case
PastCasesPanel_countColumn_title=Count 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_onNoCrIngest_message=No results will be shown because the Central Repository module was not run.
PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices
RecentFilesPanel_attachmentsTable_tabName=Recent Attachments RecentFilesPanel_attachmentsTable_tabName=Recent Attachments
@ -75,7 +75,7 @@ RecentFilesPanel_col_header_domain=Domain
RecentFilesPanel_col_header_path=Path RecentFilesPanel_col_header_path=Path
RecentFilesPanel_col_header_sender=Sender RecentFilesPanel_col_header_sender=Sender
RecentFilesPanel_docsTable_tabName=Recently Opened Documents 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. RecentFilesPanel_no_open_documents=No recently open documents found.
SizeRepresentationUtil_units_bytes=bytes SizeRepresentationUtil_units_bytes=bytes
SizeRepresentationUtil_units_gigabytes=GB SizeRepresentationUtil_units_gigabytes=GB

View File

@ -41,7 +41,7 @@ import org.sleuthkit.datamodel.DataSource;
"PastCasesPanel_caseColumn_title=Case", "PastCasesPanel_caseColumn_title=Case",
"PastCasesPanel_countColumn_title=Count", "PastCasesPanel_countColumn_title=Count",
"PastCasesPanel_onNoCrIngest_message=No results will be shown because the Central Repository module was not run.", "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",}) "PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices",})
public class PastCasesPanel extends BaseDataSourceSummaryPanel { public class PastCasesPanel extends BaseDataSourceSummaryPanel {

View File

@ -47,7 +47,7 @@ import org.sleuthkit.datamodel.DataSource;
*/ */
@Messages({ @Messages({
"RecentFilesPanel_docsTable_tabName=Recently Opened Documents", "RecentFilesPanel_docsTable_tabName=Recently Opened Documents",
"RecentFilesPanel_downloadsTable_tabName=Recently Downloads", "RecentFilesPanel_downloadsTable_tabName=Recent Downloads",
"RecentFilesPanel_attachmentsTable_tabName=Recent Attachments",}) "RecentFilesPanel_attachmentsTable_tabName=Recent Attachments",})
public final class RecentFilesPanel extends BaseDataSourceSummaryPanel { public final class RecentFilesPanel extends BaseDataSourceSummaryPanel {

View File

@ -31,6 +31,7 @@ import java.util.Collection;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.ImageUtils; 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. * Get the beginning of text from the specified AbstractFile.
* *
@ -217,7 +219,7 @@ class SummaryHelpers {
} catch (IOException ex) { } catch (IOException ex) {
return Bundle.FileSearch_documentSummary_noBytes(); return Bundle.FileSearch_documentSummary_noBytes();
} catch (TextExtractor.InitReaderException ex) { } catch (TextExtractor.InitReaderException ex) {
return Bundle.FileSearch_documentSummary_noPreview(); return Bundle.SummaryHelper_documentSummary_unable_to_read();
} }
} }

View File

@ -54,7 +54,7 @@ ExportIngestHistory_startTimeColumn=Start Time
ExportIngestHistory_versionColumn=Module Version ExportIngestHistory_versionColumn=Module Version
ExportPastCases_caseColumn_title=Case ExportPastCases_caseColumn_title=Case
ExportPastCases_countColumn_title=Count 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 ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices
ExportRecentFiles_attachmentsTable_tabName=Recent Attachments ExportRecentFiles_attachmentsTable_tabName=Recent Attachments
ExportRecentFiles_col_head_date=Date ExportRecentFiles_col_head_date=Date

View File

@ -37,7 +37,7 @@ import org.sleuthkit.datamodel.DataSource;
@Messages({ @Messages({
"ExportPastCases_caseColumn_title=Case", "ExportPastCases_caseColumn_title=Case",
"ExportPastCases_countColumn_title=Count", "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",}) "ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices",})
class ExportPastCases { class ExportPastCases {

View File

@ -384,6 +384,20 @@ final class RegexQuery implements KeywordSearchQuery {
} }
// Replace all non numeric at the end of the hit. // Replace all non numeric at the end of the hit.
hit = hit.replaceAll("[^0-9]$", ""); 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--;
}
} }
/** /**

View File

@ -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_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis.
ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s.
ChromeCacheExtractor.moduleName=ChromeCacheExtractor 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} ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3}
DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_AndroidMedia=Android Media Card
DataSourceUsage_DJU_Drone_DAT=DJI Internal SD 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. Firefox.getDlV24.errMsg.errParsingArtifacts={0}: Error parsing {1} Firefox web download artifacts.
Progress_Message_Analyze_Registry=Analyzing Registry Files Progress_Message_Analyze_Registry=Analyzing Registry Files
Progress_Message_Analyze_Usage=Data Sources Usage Analysis Progress_Message_Analyze_Usage=Data Sources Usage Analysis
# {0} - browserName
Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0} Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0}
# {0} - browserName
Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0} Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0}
Progress_Message_Chrome_Cache=Chrome Cache Progress_Message_Chrome_Cache=Chrome Cache
# {0} - browserName
Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0} Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0}
# {0} - browserName
Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0} Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0}
Progress_Message_Chrome_FormHistory=Chrome Form History Progress_Message_Chrome_FormHistory=Chrome Form History
# {0} - browserName
Progress_Message_Chrome_History=Chrome History Browser {0} Progress_Message_Chrome_History=Chrome History Browser {0}
# {0} - browserName
Progress_Message_Chrome_Logins=Chrome Logins Browser {0} Progress_Message_Chrome_Logins=Chrome Logins Browser {0}
Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks
Progress_Message_Edge_Cookies=Microsoft Edge Cookies Progress_Message_Edge_Cookies=Microsoft Edge Cookies

View File

@ -592,8 +592,13 @@ final class ChromeCacheExtractor {
// see if it is cached // see if it is cached
String fileTableKey = cacheFolderName + cacheFileName; 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)) { 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 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.selfAddress = cacheAdress;
this.cacheFileCopy = cacheFileCopy; this.cacheFileCopy = cacheFileCopy;
@ -1315,7 +1320,11 @@ final class ChromeCacheExtractor {
int entryOffset = DATAFILE_HDR_SIZE + cacheAdress.getStartBlock() * cacheAdress.getBlockSize(); int entryOffset = DATAFILE_HDR_SIZE + cacheAdress.getStartBlock() * cacheAdress.getBlockSize();
// reposition the buffer to the the correct offset // 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; hash = fileROBuf.getInt() & UINT32_MASK;
@ -1364,11 +1373,13 @@ final class ChromeCacheExtractor {
if (longKeyAddresses != null) { if (longKeyAddresses != null) {
// Key is stored outside of the entry // Key is stored outside of the entry
try { try {
CacheDataSegment data = new CacheDataSegment(longKeyAddresses, this.keyLen, true); if (longKeyAddresses.getFilename() != null) {
key = data.getDataString(); CacheDataSegment data = new CacheDataSegment(longKeyAddresses, this.keyLen, true);
key = data.getDataString();
}
} catch (TskCoreException | IngestModuleException ex) { } catch (TskCoreException | IngestModuleException ex) {
throw new TskCoreException(String.format("Failed to get external key from address %s", longKeyAddresses)); //NON-NLS throw new TskCoreException(String.format("Failed to get external key from address %s", longKeyAddresses)); //NON-NLS
} }
} }
else { // key stored within entry else { // key stored within entry
StringBuilder strBuilder = new StringBuilder(MAX_KEY_LEN); StringBuilder strBuilder = new StringBuilder(MAX_KEY_LEN);

View File

@ -318,7 +318,13 @@ final class ExtractZoneIdentifier extends Extract {
*/ */
ZoneIdentifierInfo(AbstractFile zoneFile) throws IOException { ZoneIdentifierInfo(AbstractFile zoneFile) throws IOException {
fileName = zoneFile.getName(); 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);
}
} }
/** /**