19package org.sleuthkit.datamodel;
21import com.google.common.annotations.Beta;
22import java.io.Serializable;
23import java.io.UnsupportedEncodingException;
24import java.sql.SQLException;
25import java.text.MessageFormat;
26import java.util.ArrayList;
27import java.util.Collection;
28import java.util.Collections;
29import java.util.HashMap;
30import java.util.HashSet;
33import java.util.Objects;
34import java.util.ResourceBundle;
36import java.util.stream.Collectors;
37import java.util.stream.Stream;
38import org.sleuthkit.datamodel.Blackboard.BlackboardException;
39import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
40import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
41import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
54public abstract class BlackboardArtifact
implements Content {
56 private static final ResourceBundle bundle = ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle");
57 private final long artifactId;
58 private final long sourceObjId;
59 private final long artifactObjId;
60 private final Long dataSourceObjId;
61 private final int artifactTypeId;
62 private final String artifactTypeName;
63 private final String displayName;
66 private final List<BlackboardAttribute> attrsCache =
new ArrayList<BlackboardAttribute>();
67 private boolean loadedCacheFromDb =
false;
68 private volatile Content parent;
69 private volatile String uniquePath;
71 private byte[] contentBytes =
null;
73 private volatile boolean checkedHasChildren;
74 private volatile boolean hasChildren;
75 private volatile int childrenCount;
97 BlackboardArtifact(
SleuthkitCase sleuthkitCase,
long artifactID,
long sourceObjId,
long artifactObjId, Long dataSourceObjId,
int artifactTypeID, String artifactTypeName, String displayName,
ReviewStatus reviewStatus) {
99 this.sleuthkitCase = sleuthkitCase;
100 this.artifactId = artifactID;
101 this.sourceObjId = sourceObjId;
102 this.artifactObjId = artifactObjId;
103 this.artifactTypeId = artifactTypeID;
104 this.dataSourceObjId = dataSourceObjId;
105 this.artifactTypeName = artifactTypeName;
106 this.displayName = displayName;
107 this.reviewStatus = reviewStatus;
109 this.checkedHasChildren =
false;
110 this.hasChildren =
false;
111 this.childrenCount = -1;
135 BlackboardArtifact(
SleuthkitCase sleuthkitCase,
long artifactID,
long sourceObjId,
long artifactObjID, Long dataSourceObjID,
int artifactTypeID, String artifactTypeName, String displayName,
ReviewStatus reviewStatus,
boolean isNew) {
136 this(sleuthkitCase, artifactID, sourceObjId, artifactObjID, dataSourceObjID, artifactTypeID, artifactTypeName, displayName, reviewStatus);
143 this.loadedCacheFromDb =
true;
154 return sleuthkitCase;
163 return this.artifactId;
173 return this.sourceObjId;
183 return this.dataSourceObjId;
192 return this.artifactTypeId;
204 if (standardTypesValue !=
null) {
205 return standardTypesValue;
217 return this.artifactTypeName;
226 return this.displayName;
238 StringBuilder shortDescription =
new StringBuilder(
"");
239 if (BlackboardArtifact.Type.STANDARD_TYPES.get(artifactTypeId) !=
null) {
241 case TSK_WIFI_NETWORK_ADAPTER:
244 case TSK_WIFI_NETWORK:
247 case TSK_REMOTE_DRIVE:
250 case TSK_SERVICE_ACCOUNT:
251 case TSK_SCREEN_SHOTS:
252 case TSK_DELETED_PROG:
255 case TSK_PROG_NOTIFICATIONS:
257 case TSK_RECENT_OBJECT:
258 case TSK_USER_DEVICE_EVENT:
259 case TSK_WEB_SEARCH_QUERY:
262 case TSK_BLUETOOTH_PAIRING:
271 case TSK_WEB_CATEGORIZATION:
272 case TSK_BLUETOOTH_ADAPTER:
274 case TSK_GPS_BOOKMARK:
275 case TSK_GPS_LAST_KNOWN_LOCATION:
279 case TSK_WEB_FORM_AUTOFILL:
282 case TSK_WEB_ACCOUNT_TYPE:
285 case TSK_HASHSET_HIT:
286 case TSK_INTERESTING_ARTIFACT_HIT:
287 case TSK_INTERESTING_FILE_HIT:
288 case TSK_INTERESTING_ITEM:
292 case TSK_ENCRYPTION_DETECTED:
293 case TSK_ENCRYPTION_SUSPECTED:
294 case TSK_OBJECT_DETECTED:
295 case TSK_USER_CONTENT_SUSPECTED:
296 case TSK_VERIFICATION_FAILED:
299 case TSK_DATA_SOURCE_USAGE:
300 case TSK_CALENDAR_ENTRY:
303 case TSK_WEB_BOOKMARK:
305 case TSK_WEB_DOWNLOAD:
306 case TSK_WEB_HISTORY:
310 case TSK_KEYWORD_HIT:
313 case TSK_DEVICE_ATTACHED:
319 case TSK_SPEED_DIAL_ENTRY:
320 case TSK_WEB_FORM_ADDRESS:
364 shortDescription.append(
" ");
365 shortDescription.append(MessageFormat.format(bundle.getString(
"BlackboardArtifact.shortDescriptionDate.text"), date.
getDisplayString()));
392 reviewStatus = newStatus;
407 attribute.setArtifactId(artifactId);
410 attrsCache.add(attribute);
422 ArrayList<BlackboardAttribute> attributes;
423 if (
false == loadedCacheFromDb) {
426 attrsCache.addAll(attributes);
427 loadedCacheFromDb =
true;
429 attributes =
new ArrayList<>(attrsCache);
440 void setAttributes(List<BlackboardAttribute> attributes) {
442 attrsCache.addAll(attributes);
443 loadedCacheFromDb =
true;
463 if (attribute.getAttributeType().equals(attributeType)) {
480 if (attributes.isEmpty()) {
484 attribute.setArtifactId(artifactId);
488 attrsCache.addAll(attributes);
508 if (Objects.isNull(attributes) || attributes.isEmpty()) {
509 throw new TskCoreException(
"Illegal argument passed to addAttributes: null or empty attributes passed to addAttributes");
511 if (Objects.isNull(caseDbTransaction)) {
512 throw new TskCoreException(
"Illegal argument passed to addAttributes: null caseDbTransaction passed to addAttributes");
516 attribute.setArtifactId(artifactId);
518 getSleuthkitCase().addBlackBoardAttribute(attribute, artifactTypeId, caseDbTransaction.getConnection());
520 attrsCache.addAll(attributes);
521 }
catch (SQLException ex) {
537 if (uniquePath ==
null) {
538 String tempUniquePath =
"";
540 if (myParent !=
null) {
545 uniquePath = tempUniquePath;
552 if (parent ==
null) {
568 return new ArrayList<BlackboardArtifact>();
573 return sleuthkitCase.getBlackboard().getAnalysisResults(artifactObjId);
578 return sleuthkitCase.getBlackboard().getDataArtifactsBySource(artifactObjId);
583 return sleuthkitCase.getScoringManager().getAggregateScore(artifactObjId);
589 return sleuthkitCase.getBlackboard().getAnalysisResults(artifactObjId, artifactType.getTypeID());
605 return new ArrayList<BlackboardArtifact>();
621 return new ArrayList<BlackboardArtifact>();
636 return new ArrayList<BlackboardArtifact>();
750 return new ArrayList<>();
763 return new HashSet<String>();
782 throw new TskCoreException(
"Cannot create artifact of an artifact. Not supported.");
792 AnalysisResultAdded resultAdded = sleuthkitCase.getBlackboard().newAnalysisResult(artifactType, this.
getId(), dataSourceId, score, conclusion, configuration, justification, attributesList, trans);
806 AnalysisResultAdded resultAdded = sleuthkitCase.getBlackboard().newAnalysisResult(artifactType, this.
getId(), dataSourceId, score, conclusion, configuration, justification, attributesList, trans);
818 throw new TskCoreException(
"Cannot create data artifact of an artifact. Not supported.");
823 throw new TskCoreException(
"Cannot create data artifact of an artifact. Not supported.");
846 throw new TskCoreException(
"Cannot create artifact of an artifact. Not supported.");
859 return visitor.
visit(
this);
871 if (
object ==
null) {
874 if (getClass() !=
object.getClass()) {
877 final BlackboardArtifact other = (BlackboardArtifact)
object;
889 hash = 41 * hash + (int) (this.artifactId ^ (this.artifactId >>> 32));
900 return "BlackboardArtifact{" +
"artifactID=" + artifactId +
", objID=" +
getObjectID() +
", artifactObjID=" + artifactObjId +
", artifactTypeID=" + artifactTypeId +
", artifactTypeName=" + artifactTypeName +
", displayName=" + displayName +
", Case=" +
getSleuthkitCase() +
'}';
915 return visitor.
visit(
this);
927 if (contentBytes ==
null) {
929 loadArtifactContent();
935 return contentBytes.length;
962 if (contentBytes ==
null) {
963 loadArtifactContent();
966 if (0 == contentBytes.length) {
971 long readLen = Math.min(contentBytes.length - offset, len);
972 System.arraycopy(contentBytes, 0, buf, 0, (
int) readLen);
974 return (
int) readLen;
994 StringBuilder artifactContents =
new StringBuilder();
999 }
catch (TskCoreException ex) {
1000 throw new TskCoreException(
"Unable to get datasource for artifact: " + this.
toString(), ex);
1002 if (dataSource ==
null) {
1003 throw new TskCoreException(
"Datasource was null for artifact: " + this.
toString());
1008 artifactContents.append(attribute.getAttributeType().getDisplayName());
1009 artifactContents.append(
" : ");
1010 artifactContents.append(attribute.getDisplayString());
1011 artifactContents.append(System.lineSeparator());
1013 }
catch (TskCoreException ex) {
1014 throw new TskCoreException(
"Unable to get attributes for artifact: " + this.
toString(), ex);
1018 contentBytes = artifactContents.toString().getBytes(
"UTF-8");
1019 }
catch (UnsupportedEncodingException ex) {
1020 throw new TskCoreException(
"Failed to convert artifact string to bytes for artifact: " + this.
toString(), ex);
1028 public static final class Type
implements Serializable {
1030 private static final long serialVersionUID = 1L;
1420 static final Map<Integer, Type> STANDARD_TYPES = Collections.unmodifiableMap(Stream.of(
1485 ).collect(Collectors.toMap(type -> type.getTypeID(), type -> type)));
1487 private final String typeName;
1488 private final int typeID;
1489 private final String displayName;
1500 Type(
int typeID, String typeName, String displayName,
Category category) {
1501 this.typeID = typeID;
1502 this.typeName = typeName;
1503 this.displayName = displayName;
1504 this.category = category;
1522 return this.typeName;
1540 return this.displayName;
1563 }
else if (!(that instanceof Type)) {
1566 return ((Type) that).sameType(
this);
1577 private boolean sameType(
Type that) {
1591 hash = 83 * hash + Objects.hashCode(this.typeID);
1592 hash = 83 * hash + Objects.hashCode(this.displayName);
1593 hash = 83 * hash + Objects.hashCode(this.typeName);
2028 private final String label;
2029 private final int typeId;
2030 private final String displayName;
2040 private ARTIFACT_TYPE(
int typeId, String label, String displayName) {
2053 this.typeId = typeId;
2055 this.displayName = displayName;
2056 this.category = category;
2083 return this.category;
2095 for (ARTIFACT_TYPE value : ARTIFACT_TYPE.values()) {
2096 if (value.getLabel().equals(label)) {
2100 throw new IllegalArgumentException(
"No ARTIFACT_TYPE matching type: " + label);
2114 for (ARTIFACT_TYPE value : ARTIFACT_TYPE.values()) {
2115 if (value.getTypeID() ==
id) {
2119 throw new IllegalArgumentException(
"No ARTIFACT_TYPE matching type: " +
id);
2144 return visitor.
visit(
this);
2156 public enum Category {
2158 DATA_ARTIFACT(0,
"DATA_ARTIFACT", ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle").getString(
"CategoryType.DataArtifact")),
2159 ANALYSIS_RESULT(1,
"ANALYSIS_RESULT", ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle").getString(
"CategoryType.AnalysisResult"));
2161 private final Integer id;
2162 private final String name;
2163 private final String displayName;
2165 private final static Map<Integer, Category> idToCategory =
new HashMap<Integer, Category>();
2168 for (Category status : values()) {
2169 idToCategory.put(status.getID(), status);
2180 private Category(Integer
id, String name, String displayName) {
2183 this.displayName = displayName;
2194 return idToCategory.get(
id);
2228 public enum ReviewStatus {
2234 private final Integer id;
2235 private final String name;
2236 private final String displayName;
2237 private final static Map<Integer, ReviewStatus> idToStatus =
new HashMap<Integer, ReviewStatus>();
2240 for (ReviewStatus status : values()) {
2241 idToStatus.put(status.getID(), status);
2253 private ReviewStatus(Integer
id, String name, String displayNameKey) {
2256 this.displayName = ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle").getString(displayNameKey);
2267 return idToStatus.get(
id);
2320 protected BlackboardArtifact(
SleuthkitCase sleuthkitCase,
long artifactID,
long objID,
long artifactObjID,
long dataSourceObjId,
int artifactTypeID, String artifactTypeName, String displayName) {
2321 this(sleuthkitCase, artifactID, objID, artifactObjID, dataSourceObjId, artifactTypeID, artifactTypeName, displayName,
ReviewStatus.
UNDECIDED);
2340 if (loadedCacheFromDb ==
false) {
2343 attrsCache.addAll(attrs);
2344 loadedCacheFromDb =
true;
2346 ArrayList<BlackboardAttribute> filteredAttributes =
new ArrayList<BlackboardAttribute>();
2348 if (attr.getAttributeType().getTypeID() == attributeType.getTypeID()) {
2349 filteredAttributes.add(attr);
2352 return filteredAttributes;
2357 return this.artifactObjId;
2370 List<Long> childrenIDs =
new ArrayList<Long>();
2372 childrenIDs.addAll(
getSleuthkitCase().getBlackboardArtifactChildrenIds(
this));
2379 if (childrenCount != -1) {
2380 return childrenCount;
2385 hasChildren = childrenCount > 0;
2386 checkedHasChildren =
true;
2388 return childrenCount;
2393 if (checkedHasChildren ==
true) {
2399 hasChildren = childrenCount > 0;
2400 checkedHasChildren =
true;
2415 List<Content> children =
new ArrayList<>();
BlackboardAttribute.Type getAttributeType()
static final Type TSK_TL_EVENT
static final Type TSK_DEVICE_ATTACHED
static final Type TSK_EMAIL_MSG
static final Type TSK_BLUETOOTH_ADAPTER
static final Type TSK_USER_DEVICE_EVENT
static final Type TSK_RECENT_OBJECT
static final Type TSK_SERVICE_ACCOUNT
static final Type TSK_SCREEN_SHOTS
static final Type TSK_GPS_ROUTE
static final Type TSK_VERIFICATION_FAILED
static final Type TSK_WIFI_NETWORK_ADAPTER
static final Type TSK_WEB_SEARCH_QUERY
static final Type TSK_INTERESTING_FILE_HIT
static final Type TSK_CALLLOG
static final Type TSK_DEVICE_INFO
static final Type TSK_WEB_CACHE
static final Type TSK_GPS_BOOKMARK
static final Type TSK_GPS_AREA
static final Type TSK_BACKUP_EVENT
static final Type TSK_EXTRACTED_TEXT
static final Type TSK_SPEED_DIAL_ENTRY
static final Type TSK_FACE_DETECTED
static final Type TSK_EXT_MISMATCH_DETECTED
static final Type TSK_WEB_COOKIE
static final Type TSK_PREVIOUSLY_NOTABLE
static final Type TSK_WEB_FORM_ADDRESS
static final Type TSK_HASHSET_HIT
static final Type TSK_METADATA
static final Type TSK_INTERESTING_ARTIFACT_HIT
static final Type TSK_CALENDAR_ENTRY
static final Type TSK_PROG_NOTIFICATIONS
static final Type TSK_ENCRYPTION_SUSPECTED
static final Type TSK_OBJECT_DETECTED
static final Type TSK_PROG_RUN
static final Type TSK_WEB_BOOKMARK
static final Type TSK_SIM_ATTACHED
static final Type TSK_WEB_ACCOUNT_TYPE
static final Type TSK_CONTACT
static final Type TSK_REMOTE_DRIVE
static final Type TSK_USER_CONTENT_SUSPECTED
static final Type TSK_INTERESTING_ITEM
static final Type TSK_OS_INFO
static final Type TSK_WEB_HISTORY
static final Type TSK_DATA_SOURCE_USAGE
static final Type TSK_ASSOCIATED_OBJECT
static final Type TSK_WIFI_NETWORK
static final Type TSK_GPS_TRACK
static final Type TSK_INSTALLED_PROG
static final Type TSK_BLUETOOTH_PAIRING
static final Type TSK_WEB_DOWNLOAD
static final Type TSK_GPS_LAST_KNOWN_LOCATION
boolean equals(Object that)
static final Type TSK_GEN_INFO
static final Type TSK_MALWARE
static final Type TSK_WEB_FORM_AUTOFILL
static final Type TSK_ENCRYPTION_DETECTED
static final Type TSK_DELETED_PROG
static final Type TSK_METADATA_EXIF
static final Type TSK_GPS_SEARCH
static final Type TSK_ACCOUNT
static final Type TSK_PREVIOUSLY_UNSEEN
static final Type TSK_YARA_HIT
static final Type TSK_CLIPBOARD_CONTENT
static final Type TSK_PREVIOUSLY_SEEN
static final Type TSK_KEYWORD_HIT
static final Type TSK_MESSAGE
static final Type TSK_WEB_CATEGORIZATION
BlackboardArtifact getGenInfoArtifact()
List< BlackboardAttribute > getAttributes(final BlackboardAttribute.ATTRIBUTE_TYPE attributeType)
BlackboardArtifact.Type getType()
Long getDataSourceObjectID()
ArrayList< BlackboardArtifact > getAllArtifacts()
AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, Score score, String conclusion, String configuration, String justification, Collection< BlackboardAttribute > attributesList)
List< BlackboardAttribute > getAttributes()
ArrayList< BlackboardArtifact > getArtifacts(String artifactTypeName)
ArrayList< BlackboardArtifact > getArtifacts(int artifactTypeID)
void addAttributes(Collection< BlackboardAttribute > attributes)
long getArtifactsCount(int artifactTypeID)
List< Long > getChildrenIds()
long getAllArtifactsCount()
String getShortDescription()
long getArtifactsCount(BlackboardArtifact.ARTIFACT_TYPE type)
SleuthkitCase getSleuthkitCase()
AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, Score score, String conclusion, String configuration, String justification, Collection< BlackboardAttribute > attributesList, long dataSourceId)
DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection< BlackboardAttribute > attributesList)
ReviewStatus getReviewStatus()
ArrayList< BlackboardAttribute > getGenInfoAttributes(BlackboardAttribute.ATTRIBUTE_TYPE attr_type)
void addAttributes(Collection< BlackboardAttribute > attributes, final SleuthkitCase.CaseDbTransaction caseDbTransaction)
List< Content > getChildren()
List< AnalysisResult > getAnalysisResults(BlackboardArtifact.Type artifactType)
final int read(byte[] buf, long offset, long len)
List< AnalysisResult > getAllAnalysisResults()
List< DataArtifact > getAllDataArtifacts()
Set< String > getHashSetNames()
String getArtifactTypeName()
Score getAggregateScore()
void addAttribute(BlackboardAttribute attribute)
BlackboardArtifact newArtifact(int artifactTypeID)
BlackboardArtifact(SleuthkitCase sleuthkitCase, long artifactID, long objID, long artifactObjID, long dataSourceObjId, int artifactTypeID, String artifactTypeName, String displayName)
boolean equals(Object object)
void setReviewStatus(ReviewStatus newStatus)
BlackboardArtifact newArtifact(BlackboardArtifact.ARTIFACT_TYPE type)
long getArtifactsCount(String artifactTypeName)
BlackboardAttribute getAttribute(BlackboardAttribute.Type attributeType)
DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection< BlackboardAttribute > attributesList, Long osAccountId, long dataSourceId)
DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection< BlackboardAttribute > attributesList, Long osAccountId)
ArrayList< BlackboardArtifact > getArtifacts(BlackboardArtifact.ARTIFACT_TYPE type)
BlackboardArtifact getGenInfoArtifact(boolean create)
String getDisplayString()
BlackboardArtifact.Type getArtifactType(String artTypeName)
ArrayList< BlackboardAttribute > getBlackboardAttributes(final BlackboardArtifact artifact)
Content getContentById(long id)
ArrayList< BlackboardAttribute > getBlackboardAttributes(final BlackboardArtifact artifact)
void addBlackboardAttribute(BlackboardAttribute attr, int artifactTypeId)
void addBlackboardAttributes(Collection< BlackboardAttribute > attributes, int artifactTypeId)
void setReviewStatus(BlackboardArtifact artifact, BlackboardArtifact.ReviewStatus newStatus)
Blackboard getBlackboard()
TSK_GPS_LAST_KNOWN_LOCATION
TSK_INTERESTING_ARTIFACT_HIT
static ARTIFACT_TYPE fromLabel(String label)
public< T > T accept(SleuthkitItemVisitor< T > visitor)
TSK_USER_CONTENT_SUSPECTED
TSK_INTERESTING_FILE_HIT
an interesting/notable file hit
TSK_EXT_MISMATCH_DETECTED
static ARTIFACT_TYPE fromID(int id)
static Category fromID(int id)
static ReviewStatus withID(int id)