diff --git a/bindings/java/doxygen/artifact_catalog.dox b/bindings/java/doxygen/artifact_catalog.dox index 1f50c7c1ed0ace2df7b38ff0a638458a02a092fd..d27ce4a1de69effa16db8514653793981222fb9d 100644 --- a/bindings/java/doxygen/artifact_catalog.dox +++ b/bindings/java/doxygen/artifact_catalog.dox @@ -422,7 +422,16 @@ General metadata for some content. ### REQUIRED ATTRIBUTES None - +### OPTIONAL ATTRIBUTES +- TSK_DATETIME_CREATED (Timestamp the document was created) +- TSK_DATETIME_MODIFIED (Timestamp the document was modified) +- TSK_DESCRIPTION (Title of the document) +- TSK_LAST_PRINTED_DATETIME (Timestamp when document was last printed) +- TSK_ORGANIZATION (Organization/Company who owns the document) +- TSK_OWNER (Author of the document) +- TSK_PROG_NAME (Program used to create the document) +- TSK_USER_ID (Last author of the document) +- TSK_VERSION (Version number of the program used to create the document) --- ## TSK_METADATA_EXIF diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java index fe9caf98ab67f00ceb6fcb6baef72173162a160f..0e9d449e28ccab2b4ccd05c739a118ff2c6cf3aa 100755 --- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java +++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java @@ -1411,7 +1411,12 @@ public enum ATTRIBUTE_TYPE { TSK_BYTES_RECEIVED(148, "TSK_BYTES_RECEIVED", bundle.getString("BlackboardAttribute.tskbytesreceived.text"), - TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG) + TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG), + + TSK_LAST_PRINTED_DATETIME(149, "TSK_LAST_PRINTED_DATETIME", + bundle.getString("BlackboardAttribute.tsklastprinteddatetime.text"), + TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME), + ; diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties index 8e4eb394218156142eda7c22a938ef892ce76a31..16335ea7bdca9678b386461b6e9db36b52ef82ad 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties @@ -198,6 +198,7 @@ BlackboardAttribute.tskdistancefromhome.text=Distance from Homepoint BlackboardAttribute.tskhashphotodna.text=PhotoDNA Hash BlackboardAttribute.tskbytessent.text=Bytes Sent BlackboardAttribute.tskbytesreceived.text=Bytes Received +BlackboardAttribute.tsklastprinteddatetime.text=Last Printed Date AbstractFile.readLocal.exception.msg4.text=Error reading local file\: {0} AbstractFile.readLocal.exception.msg1.text=Error reading local file, local path is not set AbstractFile.readLocal.exception.msg2.text=Error reading local file, it does not exist at local path\: {0} @@ -323,6 +324,9 @@ MiscTypes.GPSBookmark.name=GPS Bookmark MiscTypes.GPSLastknown.name=GPS Last Known Location MiscTypes.GPSearch.name=GPS Search MiscTypes.GPSTrack.name=GPS Track +MiscTypes.metadataLastPrinted.name=Document Last Printed +MiscTypes.metadataLastSaved.name=Document Last Saved +MiscTypes.metadataCreated.name=Document Created RootEventType.eventTypes.name=Event Types WebTypes.webDownloads.name=Web Downloads WebTypes.webCookies.name=Web Cookies diff --git a/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java b/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java index 8790b4bcaf3a3f29625489ba69ab318a2b3c1b6c..43256938eb117da8235ba6bed79571f74a2de43a 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java +++ b/bindings/java/src/org/sleuthkit/datamodel/CommunicationsManager.java @@ -1291,6 +1291,64 @@ public List<Account.Type> getAccountTypesInUse() throws TskCoreException { } } + /** + * Gets a list of accounts that are related to the given artifact. + * + * @param artifact + * + * @return A list of distinct accounts or an empty list if none where found. + * + * @throws TskCoreException + */ + public List<Account> getAccountsRelatedToArtifact(BlackboardArtifact artifact) throws TskCoreException { + if (artifact == null) { + throw new IllegalArgumentException("null arugment passed to getAccountsRelatedToArtifact"); + } + + List<Account> accountList = new ArrayList<>(); + try (CaseDbConnection connection = db.getConnection()) { + db.acquireSingleUserCaseReadLock(); + try { + // In order to get a list of all the unique accounts in a relationship with the given aritfact + // we must first union a list of the unique account1_id in the relationship with artifact + // then the unique account2_id (inner select with union). The outter select assures the list + // of the inner select only contains unique accounts. + String query = String.format("SELECT DISTINCT (account_id), account_type_id, account_unique_identifier" + + " FROM (" + + " SELECT DISTINCT (account_id), account_type_id, account_unique_identifier" + + " FROM accounts" + + " JOIN account_relationships ON account1_id = account_id" + + " WHERE relationship_source_obj_id = %d" + + " UNION " + + " SELECT DISTINCT (account_id), account_type_id, account_unique_identifier" + + " FROM accounts" + + " JOIN account_relationships ON account2_id = account_id" + + " WHERE relationship_source_obj_id = %d)", artifact.getId(), artifact.getId()); + try (Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(query)) { + while (rs.next()) { + Account.Type accountType = null; + int accountTypeId = rs.getInt("account_type_id"); + for (Map.Entry<Account.Type, Integer> entry : accountTypeToTypeIdMap.entrySet()) { + if (entry.getValue() == accountTypeId) { + accountType = entry.getKey(); + break; + } + } + + accountList.add(new Account(rs.getInt("account_id"), accountType, rs.getString("account_unique_identifier"))); + } + } catch (SQLException ex) { + throw new TskCoreException("Unable to get account list for give artifact " + artifact.getId(), ex); + } + + } finally { + db.releaseSingleUserCaseReadLock(); + } + } + + return accountList; + } + /** * Get account_type_id for the given account type. * @@ -1327,8 +1385,6 @@ private String normalizeAccountID(Account.Type accountType, String accountUnique return normailzeAccountID; } - - /** * Builds the SQL for the given CommunicationsFilter. * diff --git a/bindings/java/src/org/sleuthkit/datamodel/Image.java b/bindings/java/src/org/sleuthkit/datamodel/Image.java index 045c14d81cef52f2a83d3ef0ae37b989dfe1babf..161e51f3adb132a14d83394f521c0349293ac93b 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Image.java +++ b/bindings/java/src/org/sleuthkit/datamodel/Image.java @@ -255,8 +255,8 @@ public List<Volume> getVolumes() throws TskCoreException { * @throws TskCoreException */ public List<FileSystem> getFileSystems() throws TskCoreException { - List<FileSystem> fs = new ArrayList<FileSystem>(); - fs.addAll(getSleuthkitCase().getFileSystems(this)); + List<FileSystem> fs = new ArrayList<>(); + fs.addAll(getSleuthkitCase().getImageFileSystems(this)); return fs; } diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index 2c2e6f32076dfd12369c428a621eac25cf3296ce..3f7ad417bcd6bc9908b30d81c26768222ce78565 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -10114,7 +10114,7 @@ public List<ContentTag> getContentTagsByContent(Content content) throws TskCoreE * row. * * @throws TskCoreException - * @Deprecated User TaggingManager.addArtifactTag instead. + * @deprecated User TaggingManager.addArtifactTag instead. */ @Deprecated public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException { diff --git a/bindings/java/src/org/sleuthkit/datamodel/TimelineEventType.java b/bindings/java/src/org/sleuthkit/datamodel/TimelineEventType.java index a6fabdadb4ea950bbc5d30c045ace5498e4ede3b..8f99e5af32c36792f65d390f349776e0b42f0aab 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/TimelineEventType.java +++ b/bindings/java/src/org/sleuthkit/datamodel/TimelineEventType.java @@ -224,7 +224,7 @@ public int compare(TimelineEventType o1, TimelineEventType o2) { builder.add(CALL_LOG, DEVICES_ATTACHED, EMAIL, EXIF, GPS_BOOKMARK, GPS_LAST_KNOWN_LOCATION, GPS_TRACKPOINT, GPS_ROUTE, GPS_SEARCH, GPS_TRACK, INSTALLED_PROGRAM, LOG_ENTRY, MESSAGE, - RECENT_DOCUMENTS, REGISTRY); + METADATA_LAST_PRINTED, METADATA_LAST_SAVED, METADATA_CREATED, RECENT_DOCUMENTS, REGISTRY); return builder.build(); } @@ -526,7 +526,35 @@ public SortedSet< TimelineEventType> getChildren() { MISC_TYPES, new BlackboardArtifact.Type(TSK_GPS_TRACK), new Type(TSK_NAME)); + + TimelineEventType METADATA_LAST_PRINTED = new TimelineEventArtifactTypeImpl(33, + getBundle().getString("MiscTypes.metadataLastPrinted.name"),// NON-NLS + MISC_TYPES, + new BlackboardArtifact.Type(TSK_METADATA), + new BlackboardAttribute.Type(TSK_LAST_PRINTED_DATETIME), + artf -> {return getBundle().getString("MiscTypes.metadataLastPrinted.name");}, + new EmptyExtractor(), + new EmptyExtractor()); + + TimelineEventType METADATA_LAST_SAVED = new TimelineEventArtifactTypeImpl(34, + getBundle().getString("MiscTypes.metadataLastSaved.name"),// NON-NLS + MISC_TYPES, + new BlackboardArtifact.Type(TSK_METADATA), + new BlackboardAttribute.Type(TSK_DATETIME_MODIFIED), + artf -> {return getBundle().getString("MiscTypes.metadataLastSaved.name");}, + new EmptyExtractor(), + new EmptyExtractor()); + + TimelineEventType METADATA_CREATED = new TimelineEventArtifactTypeImpl(35, + getBundle().getString("MiscTypes.metadataCreated.name"),// NON-NLS + MISC_TYPES, + new BlackboardArtifact.Type(TSK_METADATA), + new BlackboardAttribute.Type(TSK_DATETIME_CREATED), + artf -> {return getBundle().getString("MiscTypes.metadataCreated.name");}, + new EmptyExtractor(), + new EmptyExtractor()); + static SortedSet<? extends TimelineEventType> getCategoryTypes() { return ROOT_EVENT_TYPE.getChildren(); } diff --git a/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java index 558fda9b7f66d63e807050840ece29fa3bb63e84..52c433a6a04435ffc0765cc714460906b2a7ceb6 100755 --- a/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java +++ b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java @@ -37,7 +37,7 @@ public final class GeoArtifactsHelper extends ArtifactHelperBase { private static final BlackboardAttribute.Type WAYPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS); - private static final BlackboardAttribute.Type TRACKPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); + private static final BlackboardAttribute.Type TRACKPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); private final String programName; /** @@ -67,28 +67,32 @@ public GeoArtifactsHelper(SleuthkitCase caseDb, String moduleName, String progra * (elevation) axes. * * @param trackName The name of the GPS track, may be null. - * @param trackPoints The track points that make up the track. + * @param trackPoints The track points that make up the track. This list + * should be non-null and non-empty. * @param moreAttributes Additional attributes for the TSK_GPS_TRACK * artifact, may be null. * * @return The TSK_GPS_TRACK artifact that was added to the case database. * - * @throws TskCoreException If there is an error creating the artifact. - * @throws BlackboardException If there is a error posting the artifact to - * the blackboard. + * @throws TskCoreException If there is an error creating the + * artifact. + * @throws BlackboardException If there is a error posting the artifact + * to the blackboard. + * @throws IllegalArgumentException If the trackpoints provided are null or + * empty. */ public BlackboardArtifact addTrack(String trackName, GeoTrackPoints trackPoints, List<BlackboardAttribute> moreAttributes) throws TskCoreException, BlackboardException { - if (trackPoints == null) { - throw new IllegalArgumentException(String.format("addTrack was passed a null list of track points")); + if (trackPoints == null || trackPoints.isEmpty()) { + throw new IllegalArgumentException(String.format("addTrack was passed a null or empty list of track points")); } - BlackboardArtifact artifact = getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK); List<BlackboardAttribute> attributes = new ArrayList<>(); if (trackName != null) { attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, getModuleName(), trackName)); } + // acquire necessary attribute. If 'toAttribute' call throws an exception, an artifact will not be created for this instance. attributes.add(BlackboardJsonAttrUtil.toAttribute(TRACKPOINTS_ATTR_TYPE, getModuleName(), trackPoints)); if (programName != null) { @@ -99,13 +103,14 @@ public BlackboardArtifact addTrack(String trackName, GeoTrackPoints trackPoints, attributes.addAll(moreAttributes); } + BlackboardArtifact artifact = getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK); artifact.addAttributes(attributes); getSleuthkitCase().getBlackboard().postArtifact(artifact, getModuleName()); return artifact; - } - + } + /** * Adds a TSK_GPS_ROUTE artifact to the case database. A Global Positioning * System (GPS) route artifact records one or more waypoints entered into a @@ -117,19 +122,23 @@ public BlackboardArtifact addTrack(String trackName, GeoTrackPoints trackPoints, * @param creationTime The time at which the route was created as * milliseconds from the Java epoch of * 1970-01-01T00:00:00Z, may be null. - * @param wayPoints The waypoints that make up the route. + * @param wayPoints The waypoints that make up the route. This list + * should be non-null and non-empty. * @param moreAttributes Additional attributes for the TSK_GPS_ROUTE * artifact, may be null. * * @return The TSK_GPS_ROUTE artifact that was added to the case database. * - * @throws TskCoreException If there is an error creating the artifact. - * @throws BlackboardException If there is a error posting the artifact to - * the blackboard. + * @throws TskCoreException If there is an error creating the + * artifact. + * @throws BlackboardException If there is a error posting the artifact + * to the blackboard. + * @throws IllegalArgumentException If the waypoints provided are null or + * empty. */ public BlackboardArtifact addRoute(String routeName, Long creationTime, GeoWaypoints wayPoints, List<BlackboardAttribute> moreAttributes) throws TskCoreException, BlackboardException { - if (wayPoints == null) { - throw new IllegalArgumentException(String.format("addRoute was passed a null list of waypoints")); + if (wayPoints == null || wayPoints.isEmpty()) { + throw new IllegalArgumentException(String.format("addRoute was passed a null or empty list of waypoints")); } BlackboardArtifact artifact = getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE); @@ -159,5 +168,5 @@ public BlackboardArtifact addRoute(String routeName, Long creationTime, GeoWaypo return artifact; } - + }