Merge branch 'develop' of github.com:sleuthkit/autopsy into merge_develop

This commit is contained in:
Eugene Livis 2022-02-03 14:54:27 -05:00
commit c50170ff20
27 changed files with 383 additions and 134 deletions

View File

@ -117,11 +117,14 @@ class OtherOccurrencesNodeWorker extends SwingWorker<OtherOccurrencesData, Void>
}
int totalCount = 0;
Set<String> dataSources = new HashSet<>();
String currentCaseName = Case.getCurrentCase().getName();
for (CorrelationAttributeInstance corAttr : correlationAttributes) {
for (NodeData nodeData : OtherOccurrences.getCorrelatedInstances(deviceId, dataSourceName, corAttr).values()) {
try {
dataSources.add(OtherOccurrences.makeDataSourceString(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getDeviceID(), nodeData.getDataSourceName()));
caseNames.put(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getCorrelationAttributeInstance().getCorrelationCase());
if(!currentCaseName.equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
dataSources.add(OtherOccurrences.makeDataSourceString(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getDeviceID(), nodeData.getDataSourceName()));
caseNames.put(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getCorrelationAttributeInstance().getCorrelationCase());
}
} catch (CentralRepoException ex) {
logger.log(Level.WARNING, "Unable to get correlation case for displaying other occurrence for case: " + nodeData.getCaseName(), ex);
}

View File

@ -219,7 +219,9 @@ public class AnnotationUtils {
// if artifact is a hashset hit or interesting file and has a non-blank comment
if ((BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() == bba.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ITEM.getTypeID() == bba.getArtifactTypeID())
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == bba.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ITEM.getTypeID() == bba.getArtifactTypeID())
&& (hasTskComment(bba))) {
boolean filesetRendered = appendEntries(parent, ARTIFACT_COMMENT_CONFIG, Arrays.asList(bba), false, !contentRendered);
@ -339,7 +341,7 @@ public class AnnotationUtils {
try {
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
return tskCase.getBlackboardArtifacts(type, sourceFile.getId()).stream()
.filter((bba) -> hasTskComment(bba))
.filter((bba) -> hasTskComment(bba) || hasTskSet(bba))
.collect(Collectors.toList());
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
@ -360,6 +362,17 @@ public class AnnotationUtils {
return StringUtils.isNotBlank(tryGetAttribute(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT));
}
/**
* Returns true if the artifact contains a non-blank TSK_SET_NAME attribute.
*
* @param artifact The artifact to check.
*
* @return True if it has a non-blank TSK_SET_NAME.
*/
private static boolean hasTskSet(BlackboardArtifact artifact) {
return StringUtils.isNotBlank(tryGetAttribute(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
}
/**
* Attempts to retrieve the attribute of a particular type from a blackboard
* artifact.

View File

@ -8,6 +8,7 @@ CallLogArtifactViewer_label_date=Date
CallLogArtifactViewer_label_direction=Direction
CallLogArtifactViewer_label_duration=Duration
CallLogArtifactViewer_label_from=From
CallLogArtifactViewer_label_hostName=Host
CallLogArtifactViewer_label_to=To
CallLogArtifactViewer_suffix_local=(Local)
CallLogArtifactViewer_value_unknown=Unknown
@ -29,6 +30,7 @@ ContactArtifactViewer_heading_Source=Source
# {0} - accountIdentifer
ContactArtifactViewer_id_not_found_in_cr=Unable to find account(s) associated with contact {0} in the Central Repository.
ContactArtifactViewer_label_datasource=Data Source
ContactArtifactViewer_label_host=Host
ContactArtifactViewer_missing_account_label=Missing contact account
ContactArtifactViewer_others_header=Other
ContactArtifactViewer_persona_account_justification=Account found in Contact artifact
@ -65,6 +67,7 @@ GeneralPurposeArtifactViewer.details.sourceHeader=Source
GeneralPurposeArtifactViewer.noFile.text=\ (no longer exists)
GeneralPurposeArtifactViewer.term.label=Term
GeneralPurposeArtifactViewer.unknown.text=Unknown
GeneralPurposeArtifactViewer_details_host=Host
GeneralPurposeArtifactViewer_menuitem_copy=Copy
MessageAccountPanel.account.justification=Account found in Message artifact
MessageAccountPanel_button_create_label=Create

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.JScrollPane;
@ -36,6 +37,8 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -100,7 +103,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
CallLogViewData callLogViewData = null;
try {
callLogViewData = getCallLogViewData(artifact);
} catch (TskCoreException ex) {
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
}
List<AccountPersonaSearcherData> personaSearchDataList = new ArrayList<>();
@ -130,7 +133,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
*
* @throws TskCoreException
*/
private CallLogViewData getCallLogViewData(BlackboardArtifact artifact) throws TskCoreException {
private CallLogViewData getCallLogViewData(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException {
if (artifact == null) {
return null;
@ -239,6 +242,12 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
callLogViewData.setFromContactNameList(fromContactNames);
callLogViewData.setToContactNameList(toContactNames);
String hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) dataSource))
.map(h -> h.getName())
.orElse(null);
callLogViewData.setHostName(hostName);
}
return callLogViewData;
@ -413,9 +422,14 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
*/
@NbBundle.Messages({
"CallLogArtifactViewer_heading_Source=Source",
"CallLogArtifactViewer_label_datasource=Data Source",})
"CallLogArtifactViewer_label_datasource=Data Source",
"CallLogArtifactViewer_label_hostName=Host"})
private void updateSourceView(CallLogViewData callLogViewData) {
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_Source());
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_hostName());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, StringUtils.defaultString(callLogViewData.getHostName()));
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
}

View File

@ -33,6 +33,8 @@ final class CallLogViewData {
private String fromAccount = null;
private String toAccount = null;
private String hostName = null;
// account identifier of the device owner, if known.
// will be one of the to or from account.
private String localAccountId = null;
@ -174,4 +176,11 @@ final class CallLogViewData {
return Collections.unmodifiableList(this.fromContactNameList);
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
}

View File

@ -48,6 +48,7 @@ import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
@ -65,6 +66,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.CommunicationsManager;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.InvalidAccountIDException;
import org.sleuthkit.datamodel.TskCoreException;
@ -85,6 +87,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
private BlackboardArtifact contactArtifact;
private String contactName;
private String datasourceName;
private String hostName;
private List<BlackboardAttribute> phoneNumList = new ArrayList<>();
private List<BlackboardAttribute> emailList = new ArrayList<>();
@ -134,7 +137,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
if (artifact != null) {
try {
extractArtifactData(artifact);
} catch (TskCoreException ex) {
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
return;
}
@ -164,7 +167,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
*
* @throws TskCoreException
*/
private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException {
private void extractArtifactData(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException {
this.contactArtifact = artifact;
@ -193,6 +196,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
}
datasourceName = contactArtifact.getDataSource().getName();
hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) contactArtifact.getDataSource()))
.map(h -> h.getName())
.orElse(null);
}
/**
@ -317,9 +324,12 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
*/
@NbBundle.Messages({
"ContactArtifactViewer_heading_Source=Source",
"ContactArtifactViewer_label_datasource=Data Source",})
"ContactArtifactViewer_label_datasource=Data Source",
"ContactArtifactViewer_label_host=Host",})
private void updateSource() {
CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_heading_Source());
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_host());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, StringUtils.defaultString(hostName));
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName);
}

View File

@ -18,7 +18,6 @@
*/
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
@ -30,13 +29,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
@ -44,9 +41,10 @@ import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
@ -54,6 +52,7 @@ import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
/**
@ -154,6 +153,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
resetComponent();
if (artifact != null) {
String dataSourceName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
String hostName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
String sourceFileName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
Map<Integer, List<BlackboardAttribute>> attributeMap = new HashMap<>();
try {
@ -167,11 +167,16 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
attributeMap.put(bba.getAttributeType().getTypeID(), attrList);
}
dataSourceName = artifact.getDataSource().getName();
hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) artifact.getDataSource()))
.map(h -> h.getName())
.orElse(null);
sourceFileName = artifact.getParent().getUniquePath();
} catch (TskCoreException ex) {
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get attributes for artifact " + artifact.getArtifactID(), ex);
}
updateView(artifact, attributeMap, dataSourceName, sourceFileName);
updateView(artifact, attributeMap, dataSourceName, hostName, sourceFileName);
}
detailsScrollPane.setViewportView(detailsPanel);
detailsScrollPane.revalidate();
@ -213,6 +218,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
@NbBundle.Messages({"GeneralPurposeArtifactViewer.details.attrHeader=Details",
"GeneralPurposeArtifactViewer.details.sourceHeader=Source",
"GeneralPurposeArtifactViewer.details.dataSource=Data Source",
"GeneralPurposeArtifactViewer_details_host=Host",
"GeneralPurposeArtifactViewer.details.file=File",
"GeneralPurposeArtifactViewer.details.datesHeader=Dates"})
/**
@ -249,6 +255,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
* @param attributeMap The map of attributes that exist for the artifact.
* @param dataSourceName The name of the datasource that caused the creation
* of the artifact.
* @param hostName The host name.
* @param sourceFilePath The path of the file that caused the creation of
* the artifact.
*/
@ -260,7 +267,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
"GeneralPurposeArtifactViewer.details.otherHeader=Other",
"GeneralPurposeArtifactViewer.noFile.text= (no longer exists)"})
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) {
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String hostName, String sourceFilePath) {
final Integer artifactTypeId = artifact.getArtifactTypeID();
if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
@ -312,6 +319,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
}
}
addHeader(Bundle.GeneralPurposeArtifactViewer_details_sourceHeader());
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_host(), StringUtils.defaultString(hostName));
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_dataSource(), dataSourceName);
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
// add veritcal glue at the end

View File

@ -181,7 +181,8 @@ public class OsAccountDataPanel extends JPanel {
"OsAccountDataPanel_basic_address=Address",
"OsAccountDataPanel_basic_admin=Administrator",
"OsAccountDataPanel_basic_type=Type",
"OsAccountDataPanel_basic_creationDate=Creation Date",})
"OsAccountDataPanel_basic_creationDate=Creation Date",
"OsAccountDataPanel_basic_objId=Object ID"})
/**
* Returns the data for the Basic Properties section of the panel.
@ -212,6 +213,8 @@ public class OsAccountDataPanel extends JPanel {
Optional<Long> crTime = account.getCreationTime();
data.addData(Bundle.OsAccountDataPanel_basic_creationDate(), crTime.isPresent() ? TimeZoneUtils.getFormattedTime(crTime.get()) : "");
data.addData(Bundle.OsAccountDataPanel_basic_objId(), Long.toString(account.getId()));
section.addSectionData(data);
return section;
}

View File

@ -22,6 +22,8 @@ import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@ -38,6 +40,7 @@ import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.apache.commons.lang3.StringUtils;
@ -71,6 +74,9 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
@NbBundle.Messages("ThumbnailViewChildren.progress.cancelling=(Cancelling)")
private static final String CANCELLING_POSTIX = Bundle.ThumbnailViewChildren_progress_cancelling();
private static Image waitingIcon;
static final int IMAGES_PER_PAGE = 200;
private final ExecutorService executor = Executors.newFixedThreadPool(3,
@ -81,6 +87,23 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
private final List<List<Node>> pages = new ArrayList<>();
private int thumbSize;
/**
* @return The thumbnail to show while waiting to load the thumbnail.
*/
private static Image getWaitingIcon() {
if (waitingIcon == null) {
String imgPath = "/org/sleuthkit/autopsy/images/working_spinner.gif";
try {
waitingIcon = ImageIO.read(ThumbnailViewNode.class.getResource(imgPath));
} catch (IOException ex) {
logger.log(Level.WARNING, "There was an error loading image: " + imgPath, ex);
}
}
return waitingIcon;
}
/**
* The constructor
*
@ -260,8 +283,6 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
private final Logger logger = Logger.getLogger(ThumbnailViewNode.class.getName());
private final Image waitingIcon = Toolkit.getDefaultToolkit().createImage(ThumbnailViewNode.class.getResource("/org/sleuthkit/autopsy/images/working_spinner.gif")); //NOI18N
private SoftReference<Image> thumbCache = null;
private int thumbSize;
private final Content content;
@ -309,7 +330,8 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
waitSpinnerTimer = new Timer(1, actionEvent -> fireIconChange());
waitSpinnerTimer.start();
}
return waitingIcon;
return getWaitingIcon();
}
synchronized void setThumbSize(int iconSize) {

View File

@ -28,14 +28,13 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory;
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -70,32 +69,42 @@ public class PastCasesSummary {
*/
public static class PastCasesResult {
private final List<Pair<String, Long>> sameIdsResults;
private final List<Pair<String, Long>> taggedNotable;
private final List<Pair<String, Long>> previouslyNotable;
private final List<Pair<String, Long>> previouslySeenDevices;
private final List<Pair<String, Long>> previouslySeenResults;
/**
* Main constructor.
*
* @param sameIdsResults Data for the cases with same id table.
* @param taggedNotable Data for the tagged notable table.
* @param previouslyNotable TSK_PREVIOUSLY_NOTABLE results.
* @param previouslySeenDevices TSK_PREVIOUSLY_SEEN device results.
* @param previouslySeenResults TSK_PREVIOUSLY_SEEN non-device results.
*/
public PastCasesResult(List<Pair<String, Long>> sameIdsResults, List<Pair<String, Long>> taggedNotable) {
this.sameIdsResults = sameIdsResults;
this.taggedNotable = taggedNotable;
public PastCasesResult(List<Pair<String, Long>> previouslyNotable, List<Pair<String, Long>> previouslySeenDevices, List<Pair<String, Long>> previouslySeenResults) {
this.previouslyNotable = Collections.unmodifiableList(previouslyNotable);
this.previouslySeenDevices = Collections.unmodifiableList(previouslySeenDevices);
this.previouslySeenResults = Collections.unmodifiableList(previouslySeenResults);
}
/**
* @return Data for the cases with same id table.
* @return TSK_PREVIOUSLY_NOTABLE results.
*/
public List<Pair<String, Long>> getSameIdsResults() {
return Collections.unmodifiableList(sameIdsResults);
public List<Pair<String, Long>> getPreviouslyNotable() {
return previouslyNotable;
}
/**
* @return Data for the tagged notable table.
* @return TSK_PREVIOUSLY_SEEN device results.
*/
public List<Pair<String, Long>> getTaggedNotable() {
return Collections.unmodifiableList(taggedNotable);
public List<Pair<String, Long>> getPreviouslySeenDevices() {
return previouslySeenDevices;
}
/**
* @return TSK_PREVIOUSLY_SEEN non-device results.
*/
public List<Pair<String, Long>> getPreviouslySeenResults() {
return previouslySeenResults;
}
}
@ -105,7 +114,6 @@ public class PastCasesSummary {
));
private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_OTHER_CASES);
private static final Set<Integer> CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList(
ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(),
@ -180,11 +188,24 @@ public class PastCasesSummary {
BlackboardAttribute commentAttr = null;
try {
commentAttr = artifact.getAttribute(TYPE_COMMENT);
commentAttr = artifact.getAttribute(BlackboardAttribute.Type.TSK_OTHER_CASES);
} catch (TskCoreException ignored) {
// ignore if no attribute can be found
}
return getCasesFromAttr(commentAttr);
}
/**
* Gets a list of cases from the TSK_OTHER_CASES attribute. The cases string
* is expected to be of a form of "case1,case2...caseN".
*
* @param artifact The attribute.
*
* @return The list of cases if found or empty list if not.
*/
private static List<String> getCasesFromAttr(BlackboardAttribute commentAttr) {
if (commentAttr == null) {
return Collections.emptyList();
}
@ -197,7 +218,6 @@ public class PastCasesSummary {
return Stream.of(justCasesStr.split(CASE_SEPARATOR))
.map(String::trim)
.collect(Collectors.toList());
}
/**
@ -228,7 +248,25 @@ public class PastCasesSummary {
}
/**
* Given a TSK_PREVIOUSLY_SEEN or TSK_PREVIOUSLY_NOTABLE artifact, retrieves it's parent artifact.
* Determines a list of counts for most populated cases based on comment
* attribute.
*
* @param artifacts The list of artifacts.
*
* @return The key value pairs mapping case to counts.
*/
private static List<Pair<String, Long>> getCaseCountsFromArtifacts(List<BlackboardArtifact> artifacts) {
List<String> cases = new ArrayList<>();
for (BlackboardArtifact art : artifacts) {
cases.addAll(getCasesFromArtifact(art));
}
return getCaseCounts(cases.stream());
}
/**
* Given a TSK_PREVIOUSLY_SEEN or TSK_PREVIOUSLY_NOTABLE artifact, retrieves
* it's parent artifact.
*
* @param artifact The input artifact.
*
@ -285,28 +323,31 @@ public class PastCasesSummary {
return null;
}
SleuthkitCase skCase = caseProvider.get();
long dataSourceId = dataSource.getId();
List<String> deviceArtifactCases = new ArrayList<>();
List<String> nonDeviceArtifactCases = new ArrayList<>();
for (Integer typeId : ARTIFACT_UPDATE_TYPE_IDS) {
for (BlackboardArtifact artifact : skCase.getBlackboard().getArtifacts(typeId, dataSource.getId())) {
List<String> cases = getCasesFromArtifact(artifact);
if (cases == null || cases.isEmpty()) {
continue;
}
Blackboard blackboard = caseProvider.get().getBlackboard();
if (hasDeviceAssociatedArtifact(artifact)) {
deviceArtifactCases.addAll(cases);
} else {
nonDeviceArtifactCases.addAll(cases);
}
List<BlackboardArtifact> previouslyNotableArtifacts
= blackboard.getArtifacts(BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE.getTypeID(), dataSourceId);
List<BlackboardArtifact> previouslySeenArtifacts
= blackboard.getArtifacts(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN.getTypeID(), dataSourceId);
List<BlackboardArtifact> previouslySeenDevice = new ArrayList<>();
List<BlackboardArtifact> previouslySeenNoDevice = new ArrayList<>();
for (BlackboardArtifact art : previouslySeenArtifacts) {
if (hasDeviceAssociatedArtifact(art)) {
previouslySeenDevice.add(art);
} else {
previouslySeenNoDevice.add(art);
}
}
return new PastCasesResult(
getCaseCounts(deviceArtifactCases.stream()),
getCaseCounts(nonDeviceArtifactCases.stream())
getCaseCountsFromArtifacts(previouslyNotableArtifacts),
getCaseCountsFromArtifacts(previouslySeenDevice),
getCaseCountsFromArtifacts(previouslySeenNoDevice)
);
}
}

View File

@ -39,8 +39,6 @@ AnalysisPanel.interestingItemLabel.text=Interesting Item Hits
RecentFilesPanel.openDocsLabel.text=Recently Opened Documents
RecentFilesPanel.downloadLabel.text=Recent Downloads
RecentFilesPanel.attachmentLabel.text=Recent Attachments
PastCasesPanel.notableFileLabel.text=Cases with Common Items That Were Tagged as Notable
PastCasesPanel.sameIdLabel.text=Past Cases with the Same Device IDs
DataSourceSummaryTabbedPane.noDataSourceLabel.text=No data source has been selected.
TimelinePanel.activityRangeLabel.text=Activity Range
GeolocationPanel.withinDistanceLabel.text=Locations further than 150km from a city will be listed as 'Unknown'
@ -62,3 +60,8 @@ ExportPanel.xlsxExportMessage.text=Export Data from Data Source Summary to an Ex
ExportPanel.xlsxExportButton.text=Export Summary Data
ExcelExportDialog.titleLabel.text=Data Source Summary has been exported to:
ExcelExportDialog.okButton.text=OK
PastCasesPanel_notableFileTable_tabName=Cases with Common Items That Were Tagged as Notable
PastCasesPanel.notableFileLabel.text=Cases with common items that were marked as notable
PastCasesPanel.seenDeviceLabel.text=Cases with the same device IDs (USB, Wifi, SIM, etc.)
PastCasesPanel.seenResultLabel.text=Cases with the same addresses (Email, Phone, etc.)
PastCasesPanel.warningLabel.text=NOTE: These results are from the time of ingest. They are not real-time updates.

View File

@ -42,7 +42,7 @@ ContainerPanel.unallocatedSizeValue.text=
DataSourceSummaryDialog.window.title=Data Sources Summary
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
DataSourceSummaryNode.column.files.header=Files
DataSourceSummaryNode.column.results.header=Results
DataSourceSummaryNode.column.results.header=Artifacts
DataSourceSummaryNode.column.status.header=Ingest Status
DataSourceSummaryNode.column.tags.header=Tags
DataSourceSummaryNode.column.type.header=Type
@ -66,9 +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 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
RecentFilesPanel_col_head_date=Date
RecentFilesPanel_col_header_domain=Domain
@ -118,8 +116,6 @@ AnalysisPanel.interestingItemLabel.text=Interesting Item Hits
RecentFilesPanel.openDocsLabel.text=Recently Opened Documents
RecentFilesPanel.downloadLabel.text=Recent Downloads
RecentFilesPanel.attachmentLabel.text=Recent Attachments
PastCasesPanel.notableFileLabel.text=Cases with Common Items That Were Tagged as Notable
PastCasesPanel.sameIdLabel.text=Past Cases with the Same Device IDs
DataSourceSummaryTabbedPane.noDataSourceLabel.text=No data source has been selected.
TimelinePanel.activityRangeLabel.text=Activity Range
GeolocationPanel.withinDistanceLabel.text=Locations further than 150km from a city will be listed as 'Unknown'
@ -141,6 +137,11 @@ ExportPanel.xlsxExportMessage.text=Export Data from Data Source Summary to an Ex
ExportPanel.xlsxExportButton.text=Export Summary Data
ExcelExportDialog.titleLabel.text=Data Source Summary has been exported to:
ExcelExportDialog.okButton.text=OK
PastCasesPanel_notableFileTable_tabName=Cases with Common Items That Were Tagged as Notable
PastCasesPanel.notableFileLabel.text=Cases with common items that were marked as notable
PastCasesPanel.seenDeviceLabel.text=Cases with the same device IDs (USB, Wifi, SIM, etc.)
PastCasesPanel.seenResultLabel.text=Cases with the same addresses (Email, Phone, etc.)
PastCasesPanel.warningLabel.text=NOTE: These results are from the time of ingest. They are not real-time updates.
UserActivityPanel_noDataExists=No communication data exists
UserActivityPanel_tab_title=User Activity
UserActivityPanel_TopAccountTableModel_accountType_header=Account Type

View File

@ -121,11 +121,9 @@ IngestJobExcelExport_moduleNameTimeColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u540d
IngestJobExcelExport_sheetName=\u53d6\u8fbc\u307f\u6b74\u53f2
IngestJobExcelExport_startTimeColumn=\u30b9\u30bf\u30fc\u30c8\u6642\u9593
IngestJobExcelExport_versionColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3
PastCasesPanel.notableFileLabel.text=\u300c\u6ce8\u76ee\u300d\u3068\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u4e00\u822c\u7684\u306a\u30b1\u30fc\u30b9
PastCasesPanel.sameIdLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9
PastCasesPanel_caseColumn_title=\u30b1\u30fc\u30b9
PastCasesPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8
PastCasesPanel_notableFileTable_tabName=\u30b1\u30fc\u30b9\u3067\u306e\u5171\u901a\u306a\u6ce8\u76ee\u3059\u3079\u304d\u4e8b\u4f8b
PastCasesPanel_notableFileTable_tabName=\u300c\u6ce8\u76ee\u300d\u3068\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u4e00\u822c\u7684\u306a\u30b1\u30fc\u30b9
PastCasesPanel_onNoCrIngest_message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002
PastCasesPanel_sameIdsTable_tabName=\u540c\u3058\u30c7\u30d0\u30a4\u30b9\u3067\u306e\u904e\u53bb\u306e\u30b1\u30fc\u30b9
RecentFilesPanel.attachmentLabel.text=\u6700\u8fd1\u306e\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb
@ -213,3 +211,6 @@ UserActivityPanel_TopWebSearchTableModel_translatedResult_header=\u7ffb\u8a33\u6
UserActivityPanel_noDataExists=\u901a\u4fe1\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093
UserActivityPanel_tab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
ViewSummaryInformationAction.name.text=\u6982\u8981\u60c5\u5831\u3092\u8868\u793a
PastCasesPanel.seenDeviceLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9
PastCasesPanel.seenResultLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9
PastCasesPanel.warningLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9

View File

@ -148,7 +148,7 @@ final class DataSourceSummaryNode extends AbstractNode {
"DataSourceSummaryNode.column.status.header=Ingest Status",
"DataSourceSummaryNode.column.type.header=Type",
"DataSourceSummaryNode.column.files.header=Files",
"DataSourceSummaryNode.column.results.header=Results",
"DataSourceSummaryNode.column.results.header=Artifacts",
"DataSourceSummaryNode.column.tags.header=Tags"})
@Override
protected Sheet createSheet() {

View File

@ -21,7 +21,7 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="mainScrollPane" alignment="0" pref="300" max="32767" attributes="0"/>
<Component id="mainScrollPane" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@ -147,10 +147,10 @@
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="sameIdLabel">
<Component class="javax.swing.JLabel" name="seenResultLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="PastCasesPanel.sameIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="PastCasesPanel.seenResultLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
@ -177,7 +177,7 @@
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Container class="javax.swing.JPanel" name="sameIdPanel">
<Container class="javax.swing.JPanel" name="seenResultPanel">
<Properties>
<Property name="alignmentX" type="float" value="0.0"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
@ -191,24 +191,111 @@
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="sameIdTable"/>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="seenResultTable"/>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
</Container>
<Component class="javax.swing.Box$Filler" name="filler5">
<Component class="javax.swing.Box$Filler" name="filler4">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
<Dimension value="[0, 20]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 20]"/>
</Property>
<Property name="alignmentX" type="float" value="0.0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="seenDeviceLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="PastCasesPanel.seenDeviceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.Box$Filler" name="filler5">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 2]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 2]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 2]"/>
</Property>
<Property name="alignmentX" type="float" value="0.0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Container class="javax.swing.JPanel" name="seenDevicePanel">
<Properties>
<Property name="alignmentX" type="float" value="0.0"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 106]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 106]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 106]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="seenDeviceTable"/>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
</Container>
<Component class="javax.swing.Box$Filler" name="filler6">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 20]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 20]"/>
</Property>
<Property name="alignmentX" type="float" value="0.0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="warningLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="PastCasesPanel.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</SubComponents>

View File

@ -40,9 +40,7 @@ import org.sleuthkit.datamodel.DataSource;
@Messages({
"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 Items at Time Of Ingest",
"PastCasesPanel_sameIdsTable_tabName=Past Cases with the Same Devices",})
"PastCasesPanel_onNoCrIngest_message=No results will be shown because the Central Repository module was not run.",})
public class PastCasesPanel extends BaseDataSourceSummaryPanel {
private static final long serialVersionUID = 1L;
@ -66,12 +64,13 @@ public class PastCasesPanel extends BaseDataSourceSummaryPanel {
= Arrays.asList(CASE_COL, COUNT_COL);
private final JTablePanel<Pair<String, Long>> notableFileTable = JTablePanel.getJTablePanel(DEFAULT_TEMPLATE);
private final JTablePanel<Pair<String, Long>> sameIdTable = JTablePanel.getJTablePanel(DEFAULT_TEMPLATE);
private final JTablePanel<Pair<String, Long>> seenDeviceTable = JTablePanel.getJTablePanel(DEFAULT_TEMPLATE);
private final JTablePanel<Pair<String, Long>> seenResultTable = JTablePanel.getJTablePanel(DEFAULT_TEMPLATE);
private final List<JTablePanel<?>> tables = Arrays.asList(
notableFileTable,
sameIdTable
seenResultTable,
seenDeviceTable
);
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
@ -109,8 +108,9 @@ public class PastCasesPanel extends BaseDataSourceSummaryPanel {
* @param result The result.
*/
private void handleResult(DataFetchResult<PastCasesResult> result) {
notableFileTable.showDataFetchResult(DataFetchResult.getSubResult(result, (res) -> res.getTaggedNotable()));
sameIdTable.showDataFetchResult(DataFetchResult.getSubResult(result, (res) -> res.getSameIdsResults()));
notableFileTable.showDataFetchResult(DataFetchResult.getSubResult(result, res -> res.getPreviouslyNotable()));
seenResultTable.showDataFetchResult(DataFetchResult.getSubResult(result, res -> res.getPreviouslySeenResults()));
seenDeviceTable.showDataFetchResult(DataFetchResult.getSubResult(result, res -> res.getPreviouslySeenDevices()));
}
@Override
@ -145,10 +145,15 @@ public class PastCasesPanel extends BaseDataSourceSummaryPanel {
javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
javax.swing.JPanel notableFilePanel = notableFileTable;
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
javax.swing.JLabel sameIdLabel = new javax.swing.JLabel();
javax.swing.JLabel seenResultLabel = new javax.swing.JLabel();
javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
javax.swing.JPanel sameIdPanel = sameIdTable;
javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
javax.swing.JPanel seenResultPanel = seenResultTable;
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
javax.swing.JLabel seenDeviceLabel = new javax.swing.JLabel();
javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
javax.swing.JPanel seenDevicePanel = seenDeviceTable;
javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
javax.swing.JLabel warningLabel = new javax.swing.JLabel();
mainContentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
mainContentPanel.setLayout(new javax.swing.BoxLayout(mainContentPanel, javax.swing.BoxLayout.PAGE_AXIS));
@ -175,21 +180,39 @@ public class PastCasesPanel extends BaseDataSourceSummaryPanel {
filler2.setAlignmentX(0.0F);
mainContentPanel.add(filler2);
org.openide.awt.Mnemonics.setLocalizedText(sameIdLabel, org.openide.util.NbBundle.getMessage(PastCasesPanel.class, "PastCasesPanel.sameIdLabel.text")); // NOI18N
mainContentPanel.add(sameIdLabel);
org.openide.awt.Mnemonics.setLocalizedText(seenResultLabel, org.openide.util.NbBundle.getMessage(PastCasesPanel.class, "PastCasesPanel.seenResultLabel.text")); // NOI18N
mainContentPanel.add(seenResultLabel);
filler3.setAlignmentX(0.0F);
mainContentPanel.add(filler3);
sameIdPanel.setAlignmentX(0.0F);
sameIdPanel.setMaximumSize(new java.awt.Dimension(32767, 106));
sameIdPanel.setMinimumSize(new java.awt.Dimension(100, 106));
sameIdPanel.setPreferredSize(new java.awt.Dimension(100, 106));
mainContentPanel.add(sameIdPanel);
seenResultPanel.setAlignmentX(0.0F);
seenResultPanel.setMaximumSize(new java.awt.Dimension(32767, 106));
seenResultPanel.setMinimumSize(new java.awt.Dimension(100, 106));
seenResultPanel.setPreferredSize(new java.awt.Dimension(100, 106));
mainContentPanel.add(seenResultPanel);
filler4.setAlignmentX(0.0F);
mainContentPanel.add(filler4);
org.openide.awt.Mnemonics.setLocalizedText(seenDeviceLabel, org.openide.util.NbBundle.getMessage(PastCasesPanel.class, "PastCasesPanel.seenDeviceLabel.text")); // NOI18N
mainContentPanel.add(seenDeviceLabel);
filler5.setAlignmentX(0.0F);
mainContentPanel.add(filler5);
seenDevicePanel.setAlignmentX(0.0F);
seenDevicePanel.setMaximumSize(new java.awt.Dimension(32767, 106));
seenDevicePanel.setMinimumSize(new java.awt.Dimension(100, 106));
seenDevicePanel.setPreferredSize(new java.awt.Dimension(100, 106));
mainContentPanel.add(seenDevicePanel);
filler6.setAlignmentX(0.0F);
mainContentPanel.add(filler6);
org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(PastCasesPanel.class, "PastCasesPanel.warningLabel.text")); // NOI18N
mainContentPanel.add(warningLabel);
mainScrollPane.setViewportView(mainContentPanel);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@ -200,7 +223,7 @@ public class PastCasesPanel extends BaseDataSourceSummaryPanel {
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
.addComponent(mainScrollPane)
);
}// </editor-fold>//GEN-END:initComponents

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -36,7 +37,7 @@ import javax.swing.SwingWorker;
*/
public class SwingWorkerSequentialExecutor {
private final ExecutorService executorService = Executors.newFixedThreadPool(1);
private final ExecutorService executorService = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().setNameFormat("SwingWorkerSequentialExecutor-%d").build());
private List<? extends SwingWorker<?, ?>> workers = Collections.emptyList();
private List<Future<?>> futures = Collections.emptyList();

View File

@ -30,6 +30,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level;
import org.netbeans.api.progress.ProgressHandle;
import org.openide.util.NbBundle.Messages;
@ -143,6 +144,7 @@ class ImageWriter implements PropertyChangeListener {
})
private void startFinishImage(String dataSourceName) {
ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("ImageWriter-startFinishImage-%d").build());
synchronized (currentTasksLock) {
if (isCancelled) {
return;
@ -186,7 +188,7 @@ class ImageWriter implements PropertyChangeListener {
// The added complexity here with the Future is because we absolutely need to make sure
// the call to finishImageWriter returns before allowing the TSK data structures to be freed
// during case close.
finishTask = Executors.newSingleThreadExecutor().submit(new Callable<Integer>() {
finishTask = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws TskCoreException {
try {
@ -199,7 +201,7 @@ class ImageWriter implements PropertyChangeListener {
caseDb.updateImagePath(settings.getPath(), dataSourceId);
}
return result;
} catch (TskCoreException ex) {
} catch (Throwable ex) {
logger.log(Level.SEVERE, "Error finishing VHD image", ex); //NON-NLS
return -1;
}
@ -215,6 +217,7 @@ class ImageWriter implements PropertyChangeListener {
try {
// The call to get() can happen multiple times if the user closes the case, which is ok
result = finishTask.get();
executor.shutdownNow();
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, "Error finishing VHD image", ex); //NON-NLS
}

View File

@ -644,7 +644,6 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
if (factory.isDataSourceIngestModuleFactory()) {
String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + "-"
+ factory.getModuleDisplayName() + "-"
+ IngestModuleInfo.IngestModuleType.DATA_SOURCE_LEVEL.toString() + "-"
+ factory.getModuleVersionNumber();
for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);
@ -659,7 +658,6 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
if (factory.isFileIngestModuleFactory()) {
String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + "-"
+ factory.getModuleDisplayName() + "-"
+ IngestModuleInfo.IngestModuleType.FILE_LEVEL.toString() + "-"
+ factory.getModuleVersionNumber();
for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);

View File

@ -30,7 +30,6 @@ import javax.swing.WindowConstants;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.Executors;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
@ -291,16 +290,13 @@ class ImportCentralRepoDbProgressDialog extends javax.swing.JDialog implements P
if (referenceSetID.get() >= 0) {
// This can be slow on large reference sets
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
try {
CentralRepository.getInstance().deleteReferenceSet(referenceSetID.get());
} catch (CentralRepoException ex2) {
Logger.getLogger(ImportCentralRepoDbProgressDialog.class.getName()).log(Level.SEVERE, "Error deleting incomplete hash set from central repository", ex2);
}
new Thread(() -> {
try {
CentralRepository.getInstance().deleteReferenceSet(referenceSetID.get());
} catch (CentralRepoException ex2) {
Logger.getLogger(ImportCentralRepoDbProgressDialog.class.getName()).log(Level.SEVERE, "Error deleting incomplete hash set from central repository", ex2);
}
});
}).start();
}
}

View File

@ -54,8 +54,9 @@ ExportIngestHistory_startTimeColumn=Start Time
ExportIngestHistory_versionColumn=Module Version
ExportPastCases_caseColumn_title=Case
ExportPastCases_countColumn_title=Count
ExportPastCases_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest
ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices
ExportPastCases_notableFileTable_tabName=Cases with common notable items
ExportPastCases_seenDevicesTable_tabName=Cases with the same device IDs
ExportPastCases_seenResultsTable_tabName=Cases with the same addresses
ExportRecentFiles_attachmentsTable_tabName=Recent Attachments
ExportRecentFiles_col_head_date=Date
ExportRecentFiles_col_header_domain=Domain

View File

@ -37,8 +37,9 @@ import org.sleuthkit.datamodel.DataSource;
@Messages({
"ExportPastCases_caseColumn_title=Case",
"ExportPastCases_countColumn_title=Count",
"ExportPastCases_notableFileTable_tabName=Cases with Common Notable Items at Time Of Ingest",
"ExportPastCases_sameIdsTable_tabName=Past Cases with the Same Devices",})
"ExportPastCases_notableFileTable_tabName=Cases with common notable items",
"ExportPastCases_seenResultsTable_tabName=Cases with the same addresses",
"ExportPastCases_seenDevicesTable_tabName=Cases with the same device IDs",})
class ExportPastCases {
private final PastCasesSummary pastSummary;
@ -73,8 +74,9 @@ class ExportPastCases {
}
return Arrays.asList(
getTableExport(DEFAULT_TEMPLATE, Bundle.ExportPastCases_notableFileTable_tabName(), result.getTaggedNotable()),
getTableExport(DEFAULT_TEMPLATE, Bundle.ExportPastCases_sameIdsTable_tabName(), result.getSameIdsResults())
getTableExport(DEFAULT_TEMPLATE, Bundle.ExportPastCases_notableFileTable_tabName(), result.getPreviouslyNotable()),
getTableExport(DEFAULT_TEMPLATE, Bundle.ExportPastCases_seenResultsTable_tabName(), result.getPreviouslySeenResults()),
getTableExport(DEFAULT_TEMPLATE, Bundle.ExportPastCases_seenDevicesTable_tabName(), result.getPreviouslySeenDevices())
);
}
}

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.imagegallery.gui.drawableviews;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.Objects;
import static java.util.Objects.nonNull;
import java.util.Optional;
@ -55,7 +56,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
/** The use of SingleThreadExecutor means we can only load a single image at
* a time */
static final Executor exec = Executors.newSingleThreadExecutor();
static final Executor exec = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("DrawableUIBase-%d").build());
@FXML
BorderPane imageBorder;

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.imagegallery.gui.navpanel;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -39,7 +40,7 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.DrawableGroup;
*/
class GroupTreeItem extends TreeItem<GroupTreeNode> {
static final Executor treeInsertTread = Executors.newSingleThreadExecutor();
static final Executor treeInsertTread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("GroupTreeItem-%d").build());
GroupTreeItem getTreeItemForGroup(DrawableGroup grouping) {
if (Objects.equals(getValue().getGroup(), grouping)) {

View File

@ -449,9 +449,12 @@ class Firefox extends Extract {
NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
if (checkColumn == true) {
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
RecentActivityExtracterModuleFactory.getModuleName(),
(Long.valueOf(result.get("creationTime").toString())))); //NON-NLS
String value = result.get("creationTime").toString();
if(value != null && !value.isEmpty()) {
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
RecentActivityExtracterModuleFactory.getModuleName(),
(Long.valueOf(result.get("creationTime").toString())))); //NON-NLS
}
}
String domain = extractDomain(host);
if (domain != null && domain.isEmpty() == false) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -53,11 +53,13 @@ To make a NetBeans module:
After the module is created, you will need to do some further configuration.
<ul>
<li>Right click on the newly created module and choose "Properties".
<li>Verify that the Netbeans Platform is set to the Autopsy Platform.
<li>You will need to configure the module to be dependent on modules from within the Autopsy platform. Go to the "Libraries" area and choose "Add" in the "Module Dependencies" section. Choose the:
<ul>
<li>"Autopsy-Core" library to get access to the Autopsy services.
<li>NetBeans "Lookup API" library so that your module can be discovered by Autopsy.
</ul>
\image html projectProperties.png
<li>If you later determine that you need to pull in external JAR files, then you will use the "Wrapped Jar" section to add them in.
<li>Note, you will also need to come back to this section if you update the platform. You may need to add a new dependency for the version of the Autopsy-Core that comes with the updated platform.
<li>Autopsy requires that all modules restart Autopsy after they are installed. Configure your module this way under Build -> Packaging. Check the box that says Needs Restart on Install.