diff --git a/NEWS.txt b/NEWS.txt index 2cbd1d7b2f3ef8888a30376d618d9bca41248c3d..6940c728c0fd594815a84d97bf373e1571cf359e 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,17 @@ +---------------- VERSION 4.10.0 -------------- +C/C++: +- Removed PostgreSQL code (that was used only by Java code) +- Added Java callback support so that database inserts are done in Java. + +Java: +- Added methods and callbacks as required to allow database population to happen in Java instead of C/C++. +- Added support to allow Autopsy streaming ingest where files are added in batches. +- Added TaggingManager class and concept of a TagSet to support ProjectVic categories. +- Fixed changes to normalization and validation of emails and phone numbers. +- Added a CASE/UCO JAR file that creates JSON-LD based on TSK objects. + + + ---------------- VERSION 4.9.0 -------------- C/C++ - Removed framework project. Use Autopsy instead if you need an analysis framework. diff --git a/bindings/java/build.xml b/bindings/java/build.xml index a5c24c0204924182ac5ab781509dce51849e2a99..5dad71b5f0f0eb49b2b6b5896b5d2e9c1936b3b9 100644 --- a/bindings/java/build.xml +++ b/bindings/java/build.xml @@ -11,7 +11,7 @@ <import file="build-${os.family}.xml"/> <!-- Careful changing this because release-windows.pl updates it by pattern --> -<property name="VERSION" value="4.9.0"/> +<property name="VERSION" value="4.10.0"/> <!-- set global properties for this build --> <property name="default-jar-location" location="/usr/share/java"/> diff --git a/bindings/java/doxygen/Doxyfile b/bindings/java/doxygen/Doxyfile index 7c615e85573d81cd944dec2b9eba95450701705b..c89d48702733ea190eb4bcd62f5eddd8bb9a83a0 100644 --- a/bindings/java/doxygen/Doxyfile +++ b/bindings/java/doxygen/Doxyfile @@ -39,7 +39,7 @@ PROJECT_NAME = "Sleuth Kit Java Bindings (JNI)" # control system is used. # NOTE: This is updated by the release-unix.pl script -PROJECT_NUMBER = 4.9.0 +PROJECT_NUMBER = 4.10.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -1050,7 +1050,7 @@ GENERATE_HTML = YES # This tag requires that the tag GENERATE_HTML is set to YES. # NOTE: This is updated by the release-unix.pl script -HTML_OUTPUT = jni-docs/4.9.0/ +HTML_OUTPUT = jni-docs/4.10.0/ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index 2f07f18b0d7e11f86d2435b78e016aa99c384c5f..417369d48d5f4e1a105404b120320b72805f43ce 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -183,6 +183,7 @@ public class SleuthkitCase { private final DbType dbType; private final String caseDirPath; private SleuthkitJNI.CaseDbHandle caseHandle; + private final String caseHandleIdentifier; // Used to identify this case in the JNI cache. private String dbBackupPath; private Map<Integer, BlackboardArtifact.Type> typeIdToArtifactTypeMap; private Map<Integer, BlackboardAttribute.Type> typeIdToAttributeTypeMap; @@ -316,6 +317,7 @@ private SleuthkitCase(String dbPath, SleuthkitJNI.CaseDbHandle caseHandle, DbTyp this.databaseName = dbFile.getName(); this.connections = new SQLiteConnections(dbPath); this.caseHandle = caseHandle; + this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier(); init(); logSQLiteJDBCDriverInfo(); } @@ -344,6 +346,7 @@ private SleuthkitCase(String host, int port, String dbName, String userName, Str this.caseDirPath = caseDirPath; this.connections = new PostgreSQLConnections(host, port, dbName, userName, password); this.caseHandle = caseHandle; + this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier(); init(); } @@ -8947,11 +8950,14 @@ CaseDbConnection getConnection() throws TskCoreException { return connections.getConnection(); } - synchronized String getUniqueCaseIdentifier() throws TskCoreException { - if (caseHandle != null) { - return caseHandle.getCaseDbIdentifier(); - } - throw new TskCoreException("Case has been closed"); + /** + * Gets the string used to identify this case in the JNI cache. + * + * @return The string for this case + * @throws TskCoreException + */ + String getCaseHandleIdentifier() { + return caseHandleIdentifier; } @Override diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java index 104488c1e4fd1e6bf7e10b302d2ebcc6fd63099b..745599c240e3ca8bb2f90e04bb7c04bdedabc597 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -251,12 +251,7 @@ private static void removeFileHandle(long fileHandle, SleuthkitCase skCase) { synchronized (cacheLock) { // Remove from collection of open file handles. if (skCase != null) { - try { - getCaseHandles(skCase.getUniqueCaseIdentifier()).fileHandleCache.remove(fileHandle); - } catch (TskCoreException ex) { - // This exception will only occur if a file handle is closed as the case is being closed. - // The file will be closed by the case closing code. - } + getCaseHandles(skCase.getCaseHandleIdentifier()).fileHandleCache.remove(fileHandle); } else { // If we don't know what case the handle is from, delete the first one we find for (String caseIdentifier:caseHandlesCache.keySet()) { @@ -789,7 +784,7 @@ public static long openImage(String[] imageFiles, SleuthkitCase skCase) throws T if (skCase == null) { throw new TskCoreException("SleuthkitCase can not be null"); } - return openImage(imageFiles, 0, true, skCase.getUniqueCaseIdentifier()); + return openImage(imageFiles, 0, true, skCase.getCaseHandleIdentifier()); } /** @@ -809,7 +804,7 @@ public static long openImage(String[] imageFiles, int sSize, SleuthkitCase skCas if (skCase == null) { throw new TskCoreException("SleuthkitCase can not be null"); } - return openImage(imageFiles, sSize, true, skCase.getUniqueCaseIdentifier()); + return openImage(imageFiles, sSize, true, skCase.getCaseHandleIdentifier()); } /** @@ -898,15 +893,11 @@ private static void cacheImageHandle(SleuthkitCase skCase, List<String> imagePat final String imageKey = keyBuilder.toString(); // Get the case identifier - try { - String caseIdentifier = skCase.getUniqueCaseIdentifier(); - - synchronized (HandleCache.cacheLock) { - HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.put(imageHandle, new HashMap<>()); - HandleCache.getCaseHandles(caseIdentifier).imageHandleCache.put(imageKey, imageHandle); - } - } catch (TskCoreException ex) { - // getUniqueCaseIdentfier() will only fail if the case is closed + String caseIdentifier = skCase.getCaseHandleIdentifier(); + + synchronized (HandleCache.cacheLock) { + HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.put(imageHandle, new HashMap<>()); + HandleCache.getCaseHandles(caseIdentifier).imageHandleCache.put(imageKey, imageHandle); } } @@ -1045,7 +1036,7 @@ static long openPool(long imgHandle, long offset, SleuthkitCase skCase) throws T if (skCase == null) { caseIdentifier = HandleCache.getDefaultCaseIdentifier(); } else { - caseIdentifier = skCase.getUniqueCaseIdentifier(); + caseIdentifier = skCase.getCaseHandleIdentifier(); } // If a pool handle cache for this image does not exist, make one @@ -1092,7 +1083,7 @@ public static long openFs(long imgHandle, long fsOffset, SleuthkitCase skCase) t if (skCase == null) { caseIdentifier = HandleCache.getDefaultCaseIdentifier(); } else { - caseIdentifier = skCase.getUniqueCaseIdentifier(); + caseIdentifier = skCase.getCaseHandleIdentifier(); } final Map<Long, Long> imgOffSetToFsHandle = HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.get(imgHandle); if (imgOffSetToFsHandle == null) { @@ -1143,7 +1134,7 @@ static long openFsPool(long imgHandle, long fsOffset, long poolHandle, long pool if (skCase == null) { caseIdentifier = HandleCache.getDefaultCaseIdentifier(); } else { - caseIdentifier = skCase.getUniqueCaseIdentifier(); + caseIdentifier = skCase.getCaseHandleIdentifier(); } final Map<Long, Long> imgOffSetToFsHandle = HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.get(imgHandle); if (imgOffSetToFsHandle == null) { @@ -1200,7 +1191,7 @@ public static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM at if (skCase == null) { caseIdentifier = HandleCache.getDefaultCaseIdentifier(); } else { - caseIdentifier = skCase.getUniqueCaseIdentifier(); + caseIdentifier = skCase.getCaseHandleIdentifier(); } if (HandleCache.getCaseHandles(caseIdentifier).poolFsList.contains(fsHandle)) { withinPool = true; @@ -1224,7 +1215,7 @@ public static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM at if (skCase == null) { caseIdentifier = HandleCache.getDefaultCaseIdentifier(); } else { - caseIdentifier = skCase.getUniqueCaseIdentifier(); + caseIdentifier = skCase.getCaseHandleIdentifier(); } HandleCache.addFileHandle(caseIdentifier, fileHandle, fsHandle); diff --git a/case-uco/java/README.md b/case-uco/java/README.md new file mode 100755 index 0000000000000000000000000000000000000000..007014b826dcf04f3356e4ab395bf9a09524fa4e --- /dev/null +++ b/case-uco/java/README.md @@ -0,0 +1,16 @@ +# Sleuth Kit CASE JSON Support +This package supports exporting Sleuth Kit DataModel objects to Cyber-investigation Analysis Standard Expression (CASE). + +Clients will interface with the CaseUcoExporter class. This class contains methods to export most DataModel objects present in the Sleuth Kit Java Bindings. + +**DISCLAIMER**: All API's in this package are subject to change. + +# Building the JAR file +To build the JAR file, simply run '**ant jar**' in the case-uco/java folder. Alternatively, you can add the code to a NetBeans project and build using the regular 'build' action. + +# Configuration Properties +Some behavior of the exporter can be configured via a Java Properties object. See the table below for available configuration properties. + +| Parameter | Description | Default | +| :---: | :---: | :---: | +| exporter.relationships.includeParentChild | Include or exclude parent-child relationships from the CASE output. By default, this class will export all parent-child relationships present in The Sleuth Kit DataModel. Volume System to Volume would be an example of such a relationship. If your use case requires exporting only the Volume, this configuration property will toggle that behavior. | true | diff --git a/case-uco/java/nbproject/project.properties b/case-uco/java/nbproject/project.properties old mode 100755 new mode 100644 index 67264595338ebf0b3207ea5793314de0feebd417..46111105f3f39d5e2c299a860bd3a3a5f62eb9b4 --- a/case-uco/java/nbproject/project.properties +++ b/case-uco/java/nbproject/project.properties @@ -31,14 +31,14 @@ dist.javadoc.dir=${dist.dir}/javadoc endorsed.classpath= excludes= file.reference.gson-2.8.5.jar=lib/gson-2.8.5.jar -file.reference.sleuthkit-4.9.0.jar=lib/sleuthkit-4.9.0.jar +file.reference.sleuthkit-4.10.0.jar=lib/sleuthkit-4.10.0.jar includes=** jar.archive.disabled=${jnlp.enabled} jar.compress=false jar.index=${jnlp.enabled} javac.classpath=\ ${file.reference.gson-2.8.5.jar}:\ - ${file.reference.sleuthkit-4.9.0.jar} +${file.reference.sleuthkit-4.10.0.jar} # Space-separated list of extra javac options javac.compilerargs=-Xlint javac.deprecation=false diff --git a/case-uco/java/src/org/sleuthkit/caseuco/Annotation.java b/case-uco/java/src/org/sleuthkit/caseuco/Annotation.java index 4d4ade8da662a133f273acce25ab99a6b0749ba2..ef5e3bbfaa422901205b4ab8f56d8de746d97cb3 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/Annotation.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/Annotation.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.caseuco; +import com.google.gson.annotations.SerializedName; import java.util.ArrayList; import java.util.List; @@ -27,18 +28,19 @@ */ class Annotation extends UcoObject { - private final List<String> tag; + @SerializedName("tag") + private final List<String> tags; private final List<String> object; Annotation(String uuid) { super(uuid, "Annotation"); - tag = new ArrayList<>(); + tags = new ArrayList<>(); object = new ArrayList<>(); } Annotation addTag(String tag) { - this.tag.add(tag); + this.tags.add(tag); return this; } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/BrowserBookmark.java b/case-uco/java/src/org/sleuthkit/caseuco/BrowserBookmark.java index 89c61afaa62c1930ce4e3c1f198c74a82ee36028..8e72ff5c27a7b791048507b1784ce5b6c1548598 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/BrowserBookmark.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/BrowserBookmark.java @@ -26,8 +26,6 @@ class BrowserBookmark extends Facet { private String urlTargeted; - private String createdTime; - private String application; BrowserBookmark() { diff --git a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoExporter.java b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoExporter.java index 5c72521d231dbb1fdd9998d7a2be405f0ff36fa8..706e33c3aa6afc68fbf50e6e75a640c95921ff00 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoExporter.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoExporter.java @@ -18,9 +18,13 @@ */ package org.sleuthkit.caseuco; +import com.google.gson.Gson; +import com.google.gson.JsonElement; + import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Properties; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED; @@ -87,17 +91,31 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; - import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskData.DbType; /** - * Exports Sleuthkit DataModel objects to CASE. UcoObject is the base class for - * all CASE constructs. The export objects are configured to be serialized with - * Gson. + * Exports Sleuth Kit DataModel objects to CASE. The CASE JSON output is + * configured to be serialized with Gson. Each export method will produce a list + * of CASE JSON objects. Clients should loop through this list and write these + * objects to any OutputStream via Gson. See the Gson documentation for more + * information on object serialization. + * + * NOTE: The exporter behavior can be configured by passing configuration + * parameters in a custom Properties instance. A list of available configuration + * properties can be found in the README.md file. */ public class CaseUcoExporter { - private final CaseUcoUUIDService uuidService; + private static final String INCLUDE_PARENT_CHILD_RELATIONSHIPS_PROP = "exporter.relationships.includeParentChild"; + private static final String DEFAULT_PARENT_CHILD_RELATIONSHIPS_VALUE = "true"; + + private final Gson gson; + + private final SleuthkitCase sleuthkitCase; + private CaseUcoUUIDService uuidService; + + private Properties props; /** * Creates a default CaseUcoExporter. @@ -106,36 +124,113 @@ public class CaseUcoExporter { * be exported. */ public CaseUcoExporter(SleuthkitCase sleuthkitCase) { - this.uuidService = new CaseUcoUUIDServiceImpl(sleuthkitCase); + this(sleuthkitCase, new Properties()); + } + + /** + * Creates a CaseUcoExporter configured to the properties present in the + * Properties instance. + * + * A list of available configuration properties can be found in the + * README.md file. + * + * @param sleuthkitCase The sleuthkit case instance containing the data to + * be exported. + * @param props Properties instance containing supported configuration + * parameters. + */ + public CaseUcoExporter(SleuthkitCase sleuthkitCase, Properties props) { + this.sleuthkitCase = sleuthkitCase; + this.props = props; + this.setUUIDService(new CaseUcoUUIDServiceImpl(sleuthkitCase)); + this.gson = new Gson(); } /** * Overrides the default UUID implementation, which is used to generate the * unique @id properties in the CASE output. Some use cases may require a - * different value for @id, such as a web service (where this value - * should contain a URL). + * different value for @id, such as a web service (where this value should + * contain a URL). * * @param uuidService A custom UUID implementation, which will be used to * generate @id values in all export methods. + * + * @return reference to this, for chaining configuration method calls. */ - public CaseUcoExporter(CaseUcoUUIDService uuidService) { + public final CaseUcoExporter setUUIDService(CaseUcoUUIDService uuidService) { this.uuidService = uuidService; + return this; + } + + /** + * Exports the SleuthkitCase instance passed during initialization to CASE. + * + * @return A collection of CASE JSON elements + * + * @throws TskCoreException If an error occurred during database access. + */ + public List<JsonElement> exportSleuthkitCase() throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + + String caseDirPath = sleuthkitCase + .getDbDirPath() + .replaceAll("\\\\", "/"); + + Trace export = new Trace(this.uuidService.createUUID(sleuthkitCase)); + + if (sleuthkitCase.getDatabaseType().equals(DbType.POSTGRESQL)) { + export.addBundle(new File() + .setFilePath(caseDirPath) + .setIsDirectory(true)); + } else { + export.addBundle(new File() + .setFilePath(caseDirPath + "/" + sleuthkitCase.getDatabaseName()) + .setIsDirectory(false)); + } + + addToOutput(export, output); + return output; } /** * Exports an AbstractFile instance to CASE. * * @param file AbstractFile instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements * - * @throws TskCoreException + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportAbstractFile(AbstractFile file) throws TskCoreException { - Trace export = new Trace(this.uuidService.createUUID(file)) - .addBundle(new ContentData() - .setMimeType(file.getMIMEType()) - .setSizeInBytes(file.getSize()) - .setMd5Hash(file.getMd5Hash())); + public List<JsonElement> exportAbstractFile(AbstractFile file) throws TskCoreException { + return exportAbstractFile(file, null); + } + + /** + * Exports an AbstractFile instance to CASE. + * + * @param file AbstractFile instance to export + * @param localPath The location of the file on secondary storage, somewhere + * other than the case. Example: local disk. This value will be ignored if + * null + * @return A collection of CASE JSON elements + * + * @throws TskCoreException If an error occurred during database access. + */ + public List<JsonElement> exportAbstractFile(AbstractFile file, String localPath) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + + ContentData contentData = new ContentData() + .setMimeType(file.getMIMEType()) + .setSizeInBytes(file.getSize()) + .setMd5Hash(file.getMd5Hash()); + + if (localPath != null) { + Trace localPathTrace = new BlankTraceNode() + .addBundle(new URL() + .setFullValue(localPath)); + contentData.setDataPayloadReferenceUrl(localPathTrace); + + addToOutput(localPathTrace, output); + } File fileExport = new File() .setAccessedTime(file.getAtime()) @@ -147,40 +242,57 @@ public UcoObject exportAbstractFile(AbstractFile file) throws TskCoreException { fileExport.setModifiedTime(file.getMtime()); fileExport.setCreatedTime(file.getCrtime()); - export.addBundle(fileExport); + Trace export = new Trace(this.uuidService.createUUID(file)) + .addBundle(contentData) + .addBundle(fileExport); + + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(file.getDataSource())); - return export; + return output; } /** * Exports a ContentTag instance to CASE. * * @param contentTag ContentTag instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportContentTag(ContentTag contentTag) { + public List<JsonElement> exportContentTag(ContentTag contentTag) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Annotation annotation = new Annotation(this.uuidService.createUUID(contentTag)) .addObject(this.uuidService.createUUID(contentTag.getContent())); annotation.setDescription(contentTag.getComment()); annotation.addTag(contentTag.getName().getDisplayName()); - return annotation; + addToOutput(annotation, output); + return output; } /** * Exports a DataSource instance to CASE. * * @param dataSource DataSource instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportDataSource(DataSource dataSource) { + public List<JsonElement> exportDataSource(DataSource dataSource) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Trace export = new Trace(this.uuidService.createUUID(dataSource)) .addBundle(new File() .setFilePath(getDataSourcePath(dataSource))) .addBundle(new ContentData() .setSizeInBytes(dataSource.getSize())); - return export; + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(this.sleuthkitCase)); + + return output; } String getDataSourcePath(DataSource dataSource) { @@ -201,38 +313,56 @@ String getDataSourcePath(DataSource dataSource) { * Exports a FileSystem instance to CASE. * * @param fileSystem FileSystem instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportFileSystem(FileSystem fileSystem) { + public List<JsonElement> exportFileSystem(FileSystem fileSystem) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Trace export = new Trace(this.uuidService.createUUID(fileSystem)) .addBundle(new org.sleuthkit.caseuco.FileSystem() .setFileSystemType(fileSystem.getFsType()) .setCluserSize(fileSystem.getBlock_size())); - return export; + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(fileSystem.getParent())); + + return output; } /** * Exports a Pool instance to CASE. * * @param pool Pool instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportPool(Pool pool) { + public List<JsonElement> exportPool(Pool pool) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Trace export = new Trace(this.uuidService.createUUID(pool)) .addBundle(new ContentData() .setSizeInBytes(pool.getSize())); - return export; + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(pool.getParent())); + + return output; } /** * Exports a Volume instance to CASE. * * @param volume Volume instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportVolume(Volume volume) { + public List<JsonElement> exportVolume(Volume volume) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Trace export = new Trace(this.uuidService.createUUID(volume)); org.sleuthkit.caseuco.Volume volumeFacet = new org.sleuthkit.caseuco.Volume(); if (volume.getLength() > 0) { @@ -242,7 +372,11 @@ public UcoObject exportVolume(Volume volume) { .addBundle(new ContentData() .setSizeInBytes(volume.getSize())); - return export; + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(volume.getParent())); + + return output; } @@ -250,30 +384,39 @@ public UcoObject exportVolume(Volume volume) { * Exports a VolumeSystem instance to CASE. * * @param volumeSystem VolumeSystem instance to export - * @return Equivalent CASE construction + * @return A collection of CASE JSON elements + * + * @throws TskCoreException If an error occurred during database access. */ - public UcoObject exportVolumeSystem(VolumeSystem volumeSystem) { + public List<JsonElement> exportVolumeSystem(VolumeSystem volumeSystem) throws TskCoreException { + List<JsonElement> output = new ArrayList<>(); + Trace export = new Trace(this.uuidService.createUUID(volumeSystem)) .addBundle(new ContentData() .setSizeInBytes(volumeSystem.getSize())); - return export; + addToOutput(export, output); + addParentChildRelationship(output, export.getId(), + this.uuidService.createUUID(volumeSystem.getParent())); + + return output; } /** * Exports a BlackboardArtifact instance to CASE. * * @param artifact BlackboardArtifact instance to export - * @return Equivalent CASE construction(s) - * @throws org.sleuthkit.datamodel.TskCoreException - * @throws org.sleuthkit.caseuco.ContentNotExportableException if the - * content could not be exported, even in part, to CASE. - * @throws - * org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException + * @return A collection of CASE JSON elements + * + * @throws TskCoreException If an error occurred during database access. + * @throws ContentNotExportableException if the content could not be + * exported, even in part, to CASE. + * @throws BlackboardJsonAttrUtil.InvalidJsonException If a JSON valued + * attribute could not be correctly deserialized. */ - public List<UcoObject> exportBlackboardArtifact(BlackboardArtifact artifact) throws TskCoreException, + public List<JsonElement> exportBlackboardArtifact(BlackboardArtifact artifact) throws TskCoreException, ContentNotExportableException, BlackboardJsonAttrUtil.InvalidJsonException { - List<UcoObject> output = new ArrayList<>(); + List<JsonElement> output = new ArrayList<>(); String uuid = this.uuidService.createUUID(artifact); int artifactTypeId = artifact.getArtifactTypeID(); @@ -378,14 +521,19 @@ public List<UcoObject> exportBlackboardArtifact(BlackboardArtifact artifact) thr assembleGpsTrack(uuid, artifact, output); } - if (!output.isEmpty()) { - return output; + if (output.isEmpty()) { + throw new ContentNotExportableException(String.format( + "Artifact [id:%d, type:%d] is either not supported " + + "or did not have any exported attributes.", artifact.getId(), artifactTypeId)); } - throw new ContentNotExportableException(); + addParentChildRelationship(output, uuid, + this.uuidService.createUUID(artifact.getParent())); + + return output; } - private void assembleWebCookie(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebCookie(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new URL() .setFullValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_URL))) @@ -410,12 +558,12 @@ private void assembleWebCookie(String uuid, BlackboardArtifact artifact, List<Uc export.addBundle(cookie); - output.add(export); - output.add(cookieDomainNode); - output.add(applicationNode); + addToOutput(export, output); + addToOutput(cookieDomainNode, output); + addToOutput(applicationNode, output); } - private void assembleWebBookmark(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebBookmark(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace applicationNode = new BlankTraceNode() .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); @@ -431,16 +579,16 @@ private void assembleWebBookmark(String uuid, BlackboardArtifact artifact, List< .addBundle(new DomainName() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DOMAIN))); - output.add(export); - output.add(applicationNode); + addToOutput(export, output); + addToOutput(applicationNode, output); } - private void assembleGenInfo(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleGenInfo(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Hash hash = new Hash(uuid, getValueIfPresent(artifact, StandardAttributeTypes.TSK_HASH_PHOTODNA)); - output.add(hash); + addToOutput(hash, output); } - private void assembleWebHistory(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebHistory(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace userNameNode = new BlankTraceNode(); IdentityFacet identityFacet = new IdentityFacet(); @@ -456,11 +604,11 @@ private void assembleWebHistory(String uuid, BlackboardArtifact artifact, List<U .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); - output.add(export); - output.add(userNameNode); + addToOutput(export, output); + addToOutput(userNameNode, output); } - private void assembleWebDownload(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebDownload(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new URL() .setFullValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_URL))) @@ -470,10 +618,10 @@ private void assembleWebDownload(String uuid, BlackboardArtifact artifact, List< .setFilePath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PATH))) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); - output.add(export); + addToOutput(export, output); } - private void assembleDeviceAttached(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleDeviceAttached(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Device() .setManufacturer(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DEVICE_MAKE)) @@ -483,18 +631,18 @@ private void assembleDeviceAttached(String uuid, BlackboardArtifact artifact, Li .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_MAC_ADDRESS))); export.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME)); - output.add(export); + addToOutput(export, output); } - private void assembleHashsetHit(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleHashsetHit(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid); export.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_SET_NAME)); export.setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleInstalledProg(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleInstalledProg(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new File() .setFilePath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PATH_SOURCE))); @@ -509,10 +657,10 @@ private void assembleInstalledProg(String uuid, BlackboardArtifact artifact, Lis file.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME_CREATED)); export.addBundle(file); - output.add(export); + addToOutput(export, output); } - private void assembleRecentObject(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleRecentObject(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); @@ -529,32 +677,31 @@ private void assembleRecentObject(String uuid, BlackboardArtifact artifact, List export.addBundle(file); - output.add(export); + addToOutput(export, output); Assertion assertion = new BlankAssertionNode() .setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(assertion); - - output.add(new BlankRelationshipNode() + addToOutput(assertion, output); + addToOutput(new BlankRelationshipNode() .setSource(assertion.getId()) - .setTarget(uuid)); + .setTarget(uuid), output); } - private void assembleInterestingFileHit(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleInterestingFileHit(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid); export.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_SET_NAME)); export.setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleExtractedText(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleExtractedText(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new ExtractedString() .setStringValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_TEXT))); - output.add(export); + addToOutput(export, output); } - private void assembleEmailMessage(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleEmailMessage(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace bccNode = new BlankTraceNode() .addBundle(new EmailAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_EMAIL_BCC))); @@ -600,14 +747,14 @@ private void assembleEmailMessage(String uuid, BlackboardArtifact artifact, List .addBundle(new File() .setFilePath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PATH))); - output.add(export); - output.add(bccNode); - output.add(ccNode); - output.add(fromNode); - output.add(headerRawNode); + addToOutput(export, output); + addToOutput(bccNode, output); + addToOutput(ccNode, output); + addToOutput(fromNode, output); + addToOutput(headerRawNode, output); } - private void assembleWebSearchQuery(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebSearchQuery(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace applicationNode = new BlankTraceNode() .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); @@ -619,11 +766,11 @@ private void assembleWebSearchQuery(String uuid, BlackboardArtifact artifact, Li .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DOMAIN))) .addBundle(new ApplicationAccount() .setApplication(applicationNode)); - output.add(export); - output.add(applicationNode); + addToOutput(export, output); + addToOutput(applicationNode, output); } - private void assembleOsInfo(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleOsInfo(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Identity registeredOwnerNode = new BlankIdentityNode(); registeredOwnerNode.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_OWNER)); Identity registeredOrganizationNode = new BlankIdentityNode(); @@ -653,13 +800,14 @@ private void assembleOsInfo(String uuid, BlackboardArtifact artifact, List<UcoOb .setRegisteredOrganization(registeredOrganizationNode) .setRegisteredOwner(registeredOwnerNode) .setWindowsTempDirectory(tempDirectoryNode)); - output.add(export); - output.add(registeredOwnerNode); - output.add(registeredOrganizationNode); - output.add(tempDirectoryNode); + + addToOutput(export, output); + addToOutput(registeredOwnerNode, output); + addToOutput(registeredOrganizationNode, output); + addToOutput(tempDirectoryNode, output); } - private void assembleOsAccount(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleOsAccount(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new EmailAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_EMAIL))) @@ -688,11 +836,11 @@ private void assembleOsAccount(String uuid, BlackboardArtifact artifact, List<Uc export.addBundle(account); - output.add(export); - output.add(ownerNode); + addToOutput(export, output); + addToOutput(ownerNode, output); } - private void assembleServiceAccount(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleServiceAccount(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace inReplyToNode = new BlankTraceNode() .addBundle(new EmailAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_EMAIL_REPLYTO))); @@ -727,12 +875,12 @@ private void assembleServiceAccount(String uuid, BlackboardArtifact artifact, Li account.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME_CREATED)); export.addBundle(account); - output.add(export); - output.add(applicationNode); - output.add(inReplyToNode); + addToOutput(export, output); + addToOutput(applicationNode, output); + addToOutput(inReplyToNode, output); } - private void assembleContact(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleContact(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { EmailAddress homeAddress = new EmailAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_EMAIL_HOME)); homeAddress.setTag("Home"); @@ -767,10 +915,10 @@ private void assembleContact(String uuid, BlackboardArtifact artifact, List<UcoO .addBundle(homePhone) .addBundle(workPhone) .addBundle(mobilePhone); - output.add(export); + addToOutput(export, output); } - private void assembleMessage(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException, BlackboardJsonAttrUtil.InvalidJsonException { + private void assembleMessage(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException, BlackboardJsonAttrUtil.InvalidJsonException { Trace applicationNode = new BlankTraceNode() .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_MESSAGE_TYPE))); @@ -818,14 +966,14 @@ private void assembleMessage(String uuid, BlackboardArtifact artifact, List<UcoO }); } - output.add(export); - output.add(applicationNode); - output.add(senderNode); - output.add(fromNode); - output.add(toNode); + addToOutput(export, output); + addToOutput(applicationNode, output); + addToOutput(senderNode, output); + addToOutput(fromNode, output); + addToOutput(toNode, output); } - private void assembleMetadataExif(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleMetadataExif(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Device() .setManufacturer(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DEVICE_MAKE)) @@ -836,10 +984,10 @@ private void assembleMetadataExif(String uuid, BlackboardArtifact artifact, List .setLongitude(getDoubleIfPresent(artifact, StandardAttributeTypes.TSK_GEO_LONGITUDE))); export.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME_CREATED)); - output.add(export); + addToOutput(export, output); } - private void assembleCallog(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleCallog(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace fromNode = new BlankTraceNode() .addBundle(new PhoneAccount() .setPhoneNumber(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PHONE_NUMBER_FROM))); @@ -860,12 +1008,12 @@ private void assembleCallog(String uuid, BlackboardArtifact artifact, List<UcoOb .addBundle(new Contact() .setContactName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_NAME))); - output.add(export); - output.add(toNode); - output.add(fromNode); + addToOutput(export, output); + addToOutput(toNode, output); + addToOutput(fromNode, output); } - private void assembleCalendarEntry(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleCalendarEntry(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid); CalendarEntry calendarEntry = new CalendarEntry() @@ -881,21 +1029,21 @@ private void assembleCalendarEntry(String uuid, BlackboardArtifact artifact, Lis calendarEntry.setLocation(locationNode); export.addBundle(calendarEntry); - output.add(export); - output.add(locationNode); + addToOutput(export, output); + addToOutput(locationNode, output); } - private void assembleSpeedDialEntry(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleSpeedDialEntry(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Contact() .setContactName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_NAME_PERSON))) .addBundle(new PhoneAccount() .setPhoneNumber(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PHONE_NUMBER))); - output.add(export); + addToOutput(export, output); } - private void assembleBluetoothPairing(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleBluetoothPairing(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new MobileDevice() .setBluetoothDeviceName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DEVICE_NAME))) @@ -903,10 +1051,10 @@ private void assembleBluetoothPairing(String uuid, BlackboardArtifact artifact, .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_MAC_ADDRESS))); export.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME)); - output.add(export); + addToOutput(export, output); } - private void assembleGpsBookmark(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleGpsBookmark(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new LatLongCoordinates() .setAltitude(getDoubleIfPresent(artifact, StandardAttributeTypes.TSK_GEO_ALTITUDE)) @@ -921,10 +1069,10 @@ private void assembleGpsBookmark(String uuid, BlackboardArtifact artifact, List< export.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME)); export.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_NAME)); - output.add(export); + addToOutput(export, output); } - private void assembleGpsLastKnownLocation(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleGpsLastKnownLocation(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new LatLongCoordinates() .setAltitude(getDoubleIfPresent(artifact, StandardAttributeTypes.TSK_GEO_ALTITUDE)) @@ -939,14 +1087,14 @@ private void assembleGpsLastKnownLocation(String uuid, BlackboardArtifact artifa simpleAddress.setDescription(getValueIfPresent(artifact, StandardAttributeTypes.TSK_LOCATION)); export.addBundle(simpleAddress); - output.add(export); - output.add(locationNode); - output.add(new BlankRelationshipNode() + addToOutput(export, output); + addToOutput(locationNode, output); + addToOutput(new BlankRelationshipNode() .setSource(locationNode.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } - private void assembleGpsSearch(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleGpsSearch(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new LatLongCoordinates() .setAltitude(getDoubleIfPresent(artifact, StandardAttributeTypes.TSK_GEO_ALTITUDE)) @@ -961,30 +1109,30 @@ private void assembleGpsSearch(String uuid, BlackboardArtifact artifact, List<Uc simpleAddress.setDescription(getValueIfPresent(artifact, StandardAttributeTypes.TSK_LOCATION)); export.addBundle(simpleAddress); - output.add(export); - output.add(locationNode); - output.add(new BlankRelationshipNode() + addToOutput(export, output); + addToOutput(locationNode, output); + addToOutput(new BlankRelationshipNode() .setSource(locationNode.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } - private void assembleProgRun(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleProgRun(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME)) .setNumberOfLaunches(getIntegerIfPresent(artifact, StandardAttributeTypes.TSK_COUNT))); - output.add(export); + addToOutput(export, output); } - private void assembleEncryptionDetected(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleEncryptionDetected(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid) .setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleInterestingArtifact(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleInterestingArtifact(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid); export.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_SET_NAME)); export.setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); @@ -993,15 +1141,15 @@ private void assembleInterestingArtifact(String uuid, BlackboardArtifact artifac if (associatedArtifactId != null) { BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(associatedArtifactId); - output.add(new BlankRelationshipNode() + addToOutput(new BlankRelationshipNode() .setSource(export.getId()) - .setTarget(this.uuidService.createUUID(associatedArtifact))); + .setTarget(this.uuidService.createUUID(associatedArtifact)), output); } - output.add(export); + addToOutput(export, output); } - private void assembleGPSRoute(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleGPSRoute(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); @@ -1014,24 +1162,24 @@ private void assembleGPSRoute(String uuid, BlackboardArtifact artifact, List<Uco Location location = new BlankLocationNode(); location.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_NAME)); - output.add(export); - output.add(location); - output.add(new BlankRelationshipNode() + addToOutput(export, output); + addToOutput(location, output); + addToOutput(new BlankRelationshipNode() .setSource(location.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } - private void assembleRemoteDrive(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleRemoteDrive(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new PathRelation() .setPath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_REMOTE_PATH))) .addBundle(new PathRelation() .setPath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_LOCAL_PATH))); - output.add(export); + addToOutput(export, output); } - private void assembleAccount(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleAccount(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Account account = new Account() .setAccountType(getValueIfPresent(artifact, StandardAttributeTypes.TSK_ACCOUNT_TYPE)) .setAccountIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_ID)); @@ -1044,25 +1192,25 @@ private void assembleAccount(String uuid, BlackboardArtifact artifact, List<UcoO .addBundle(account) .addBundle(creditCardAccount); - output.add(export); + addToOutput(export, output); } - private void assembleEncryptionSuspected(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleEncryptionSuspected(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid) .setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleObjectDetected(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleObjectDetected(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid) .setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); export.setDescription(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DESCRIPTION)); - output.add(export); + addToOutput(export, output); } - private void assembleWifiNetwork(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWifiNetwork(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { WirelessNetworkConnection wirelessNetwork = new WirelessNetworkConnection() .setSSID(getValueIfPresent(artifact, StandardAttributeTypes.TSK_SSID)); @@ -1076,10 +1224,10 @@ private void assembleWifiNetwork(String uuid, BlackboardArtifact artifact, List< Trace export = new Trace(uuid) .addBundle(wirelessNetwork); - output.add(export); + addToOutput(export, output); } - private void assembleDeviceInfo(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleDeviceInfo(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new MobileDevice() .setIMEI(getValueIfPresent(artifact, StandardAttributeTypes.TSK_IMEI))) @@ -1087,49 +1235,49 @@ private void assembleDeviceInfo(String uuid, BlackboardArtifact artifact, List<U .setICCID(getValueIfPresent(artifact, StandardAttributeTypes.TSK_ICCID)) .setIMSI(getValueIfPresent(artifact, StandardAttributeTypes.TSK_IMSI))); - output.add(export); + addToOutput(export, output); } - private void assembleSimAttached(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleSimAttached(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new SIMCard() .setICCID(getValueIfPresent(artifact, StandardAttributeTypes.TSK_ICCID)) .setIMSI(getValueIfPresent(artifact, StandardAttributeTypes.TSK_IMSI))); - output.add(export); + addToOutput(export, output); } - private void assembleBluetoothAdapter(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleBluetoothAdapter(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new MACAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_MAC_ADDRESS))); - output.add(export); + addToOutput(export, output); } - private void assembleWifiNetworkAdapter(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWifiNetworkAdapter(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new MACAddress() .setValue(getValueIfPresent(artifact, StandardAttributeTypes.TSK_MAC_ADDRESS))); - output.add(export); + addToOutput(export, output); } - private void assembleVerificationFailed(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleVerificationFailed(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid); export.setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleDataSourceUsage(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleDataSourceUsage(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid); export.setDescription(getValueIfPresent(artifact, StandardAttributeTypes.TSK_DESCRIPTION)); - output.add(export); + addToOutput(export, output); } - private void assembleWebFormAddress(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebFormAddress(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { SimpleAddress simpleAddress = new SimpleAddress(); simpleAddress.setDescription(getValueIfPresent(artifact, StandardAttributeTypes.TSK_LOCATION)); @@ -1146,15 +1294,15 @@ private void assembleWebFormAddress(String uuid, BlackboardArtifact artifact, Li Person person = new BlankPersonNode(); person.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_NAME_PERSON)); - output.add(export); - output.add(person); - output.add(new BlankRelationshipNode() + addToOutput(export, output); + addToOutput(person, output); + addToOutput(new BlankRelationshipNode() .setSource(person.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } - private void assembleWebCache(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleWebCache(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new PathRelation() .setPath(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PATH))) @@ -1165,10 +1313,10 @@ private void assembleWebCache(String uuid, BlackboardArtifact artifact, List<Uco export.setCreatedTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME_CREATED)); - output.add(export); + addToOutput(export, output); } - private void assembleTimelineEvent(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleTimelineEvent(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Action export = new Action(uuid) .setStartTime(getLongIfPresent(artifact, StandardAttributeTypes.TSK_DATETIME)); @@ -1184,48 +1332,48 @@ private void assembleTimelineEvent(String uuid, BlackboardArtifact artifact, Lis .addBundle(new ActionArgument() .setArgumentName(timelineEventType.get().getDisplayName())); - output.add(actionArg); - output.add(new BlankRelationshipNode() + addToOutput(actionArg, output); + addToOutput(new BlankRelationshipNode() .setSource(actionArg.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } } - output.add(export); + addToOutput(export, output); } - private void assembleClipboardContent(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleClipboardContent(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Note() .setText(getValueIfPresent(artifact, StandardAttributeTypes.TSK_TEXT))); - output.add(export); + addToOutput(export, output); } - private void assembleAssociatedObject(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleAssociatedObject(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid); - output.add(export); + addToOutput(export, output); BlackboardAttribute associatedArtifactID = artifact.getAttribute(StandardAttributeTypes.TSK_ASSOCIATED_ARTIFACT); if (associatedArtifactID != null) { long artifactID = associatedArtifactID.getValueLong(); BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getArtifactByArtifactId(artifactID); if (associatedArtifact != null) { - output.add(new BlankRelationshipNode() + addToOutput(new BlankRelationshipNode() .setSource(uuid) - .setTarget(this.uuidService.createUUID(associatedArtifact))); + .setTarget(this.uuidService.createUUID(associatedArtifact)), output); } } } - private void assembleUserContentSuspected(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleUserContentSuspected(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Assertion export = new Assertion(uuid); export.setStatement(getValueIfPresent(artifact, StandardAttributeTypes.TSK_COMMENT)); - output.add(export); + addToOutput(export, output); } - private void assembleMetadata(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException { + private void assembleMetadata(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException { Trace export = new Trace(uuid) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME)) @@ -1253,19 +1401,19 @@ private void assembleMetadata(String uuid, BlackboardArtifact artifact, List<Uco lastAuthor.setTag("Last Author"); lastAuthor.setName(getValueIfPresent(artifact, StandardAttributeTypes.TSK_USER_ID)); - output.add(export); - output.add(owner); - output.add(organization); - output.add(new BlankRelationshipNode() + addToOutput(export, output); + addToOutput(owner, output); + addToOutput(organization, output); + addToOutput(new BlankRelationshipNode() .setSource(organization.getId()) - .setTarget(export.getId())); - output.add(lastAuthor); - output.add(new BlankRelationshipNode() + .setTarget(export.getId()), output); + addToOutput(lastAuthor, output); + addToOutput(new BlankRelationshipNode() .setSource(lastAuthor.getId()) - .setTarget(export.getId())); + .setTarget(export.getId()), output); } - private void assembleGpsTrack(String uuid, BlackboardArtifact artifact, List<UcoObject> output) throws TskCoreException, BlackboardJsonAttrUtil.InvalidJsonException { + private void assembleGpsTrack(String uuid, BlackboardArtifact artifact, List<JsonElement> output) throws TskCoreException, BlackboardJsonAttrUtil.InvalidJsonException { Trace export = new Trace(uuid) .addBundle(new Application() .setApplicationIdentifier(getValueIfPresent(artifact, StandardAttributeTypes.TSK_PROG_NAME))); @@ -1282,7 +1430,7 @@ private void assembleGpsTrack(String uuid, BlackboardArtifact artifact, List<Uco } } - output.add(export); + addToOutput(export, output); } /** @@ -1335,4 +1483,28 @@ private String getValueIfPresent(BlackboardArtifact artifact, BlackboardAttribut return null; } } + + /** + * Add the parent-child relationship, if configured to do so. + */ + private void addParentChildRelationship(List<JsonElement> output, String sourceId, String parentId) { + String parentChildProperty = this.props.getProperty(INCLUDE_PARENT_CHILD_RELATIONSHIPS_PROP, + DEFAULT_PARENT_CHILD_RELATIONSHIPS_VALUE); + + if (Boolean.valueOf(parentChildProperty)) { + addToOutput(new BlankRelationshipNode() + .setSource(sourceId) + .setTarget(parentId) + .setKindOfRelationship("contained-within") + .isDirectional(true), output); + } + } + + /** + * Adds a given CASE export object to the JSON output that will be consumed + * by the client. + */ + private void addToOutput(UcoObject ucoObject, List<JsonElement> output) { + output.add(gson.toJsonTree(ucoObject)); + } } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDService.java b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDService.java index 23d8265149ab7f8680bb5b7b647509a1f9814664..5bae8a470f9c08bd2ae631691e2a7063ecb6d7f0 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDService.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDService.java @@ -20,22 +20,28 @@ import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.SleuthkitCase; /** * Providing a way to customize UUIDs is a necessary feature to promote the - * reuse of the CaseUcoExporter class. IDs in a REST API use case would prefer + * reuse of the CaseUcoExporter class. For example, REST API IDs would prefer * links to the relevant endpoints and IDs in a standalone TSK application may - * prefer a combination of object id, case id, and time stamp. A runtime object - * that provides this service is a good way to address content objects that - * reference other content objects. For example, when the CaesUcoExporter is - * asked to export a TSK_ASSOCIATED_ARTIFACT_HIT or a ContentTag, it'll also - * need to export the reference to the underlying content as well. It wouldn't - * be very user friendly if we asked for these IDs up front, so instead it's - * quite handy to have some service that can be set once and forgotten about - * during execution. + * prefer a combination of object id, case name, and time stamp. A runtime + * object that provides this service is a nice 'hands-off' approach to exporting + * content that references other content objects. For example, + * TSK_ASSOCIATED_ARTIFACT_HIT and ContentTag both reference other content + * instances that need to be linked in the CASE output. Creating a class for + * this task guarantees consistent IDs and ensures the API is simple to use. + * + * CaseUcoExporter already ships with a default implementation of this class. + * The default implementation will use the object id and database name. To + * override the default, please refer to the CaseUcoExporter documentation. */ public interface CaseUcoUUIDService { public String createUUID(Content content); + public String createUUID(ContentTag contentTag); + + public String createUUID(SleuthkitCase sleuthkitCase); } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDServiceImpl.java b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDServiceImpl.java index 7b1fcd424588838eb7351e5c168e1df89cfe28a8..d42b0e89f5b2ca6a829d94a2ae292bbba1d4ac68 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDServiceImpl.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/CaseUcoUUIDServiceImpl.java @@ -37,11 +37,16 @@ class CaseUcoUUIDServiceImpl implements CaseUcoUUIDService { @Override public String createUUID(Content content) { - return "content" + "-" + content.getId() + "_" + databaseName; + return "_:content-" + content.getId() + "_" + databaseName; } @Override public String createUUID(ContentTag contentTag) { - return "tag" + "-" + contentTag.getId() + "_" + databaseName; + return "_:tag-" + contentTag.getId() + "_" + databaseName; + } + + @Override + public String createUUID(SleuthkitCase sleuthkitCase) { + return "_:case-" + sleuthkitCase.getDatabaseName(); } } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/ContentData.java b/case-uco/java/src/org/sleuthkit/caseuco/ContentData.java index 9d6e85485a64fb7d6c1de85f0fd7500bc5ab5b73..cf317eed75955477af7e57d0cca4ea2ee0a33169 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/ContentData.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/ContentData.java @@ -40,6 +40,8 @@ class ContentData extends Facet { private String dataPayload; private String owner; + + private String dataPayloadReferenceUrl; ContentData() { super(ContentData.class.getSimpleName()); @@ -72,4 +74,9 @@ ContentData setOwner(Identity owner) { this.owner = owner.getId(); return this; } + + ContentData setDataPayloadReferenceUrl(UcoObject url) { + this.dataPayloadReferenceUrl = url.getId(); + return this; + } } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/ContentNotExportableException.java b/case-uco/java/src/org/sleuthkit/caseuco/ContentNotExportableException.java index abb248ce9650f1dac409be952c53154c1b5f8892..4d16855cb5724f72223c7a2eb39d9f0cccc25480 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/ContentNotExportableException.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/ContentNotExportableException.java @@ -23,4 +23,8 @@ */ public class ContentNotExportableException extends Exception { private static final long serialVersionUID = 1L; + + ContentNotExportableException(String msg) { + super(msg); + } } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/Message.java b/case-uco/java/src/org/sleuthkit/caseuco/Message.java index e87ad819ab0eb912ab1d37e600fdd2410765c15a..fb61b9bea59901b4c8e2f758134fa5617f4fde0f 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/Message.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/Message.java @@ -31,7 +31,7 @@ class Message extends Facet { private String application; - String sentTime; + private String sentTime; private String messageType; diff --git a/case-uco/java/src/org/sleuthkit/caseuco/Relationship.java b/case-uco/java/src/org/sleuthkit/caseuco/Relationship.java index f8a18995f382c7944efafb4c67ea856e80e7dd52..27d4563fbb8c4a28a132aec826c90d3b0d8af631 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/Relationship.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/Relationship.java @@ -27,6 +27,10 @@ class Relationship extends UcoObject { private String source; private String target; + + private String kindOfRelationship; + + private Boolean isDirectional; Relationship(String id) { super(id, "Relationship"); @@ -41,4 +45,14 @@ Relationship setTarget(String target) { this.target = target; return this; } + + Relationship setKindOfRelationship(String kindOfRelationship) { + this.kindOfRelationship = kindOfRelationship; + return this; + } + + Relationship isDirectional(boolean isDirectional) { + this.isDirectional = isDirectional; + return this; + } } diff --git a/case-uco/java/src/org/sleuthkit/caseuco/SMSMessage.java b/case-uco/java/src/org/sleuthkit/caseuco/SMSMessage.java index 170ee6864867874155066e4f19db95d39fe5a1cc..c2012bd8c6b485d4be83e59da8bb3309252a16a2 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/SMSMessage.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/SMSMessage.java @@ -24,7 +24,7 @@ */ class SMSMessage extends Facet { - Boolean isRead; + private Boolean isRead; SMSMessage() { super(SMSMessage.class.getSimpleName()); diff --git a/case-uco/java/src/org/sleuthkit/caseuco/UcoObject.java b/case-uco/java/src/org/sleuthkit/caseuco/UcoObject.java index a87917ea57383c33c4237b36ce7109e650e6ee07..14c49bee68092898c292d5a6479278fdda9ea6a6 100755 --- a/case-uco/java/src/org/sleuthkit/caseuco/UcoObject.java +++ b/case-uco/java/src/org/sleuthkit/caseuco/UcoObject.java @@ -25,7 +25,7 @@ /** * Base class for all CASE/UCO constructs. */ -public abstract class UcoObject { +abstract class UcoObject { @SerializedName("@id") private String id; diff --git a/configure.ac b/configure.ac index 17845711871eafde8ce7a41b9a0b8dca4c3152c8..8e76b034703b9610b6f972743e441914b15ed83c 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(sleuthkit, 4.9.0) +AC_INIT(sleuthkit, 4.10.0) m4_include([m4/ax_pthread.m4]) dnl include the version from 1.12.1. This will work for m4_include([m4/cppunit.m4]) diff --git a/debian/changelog b/debian/changelog index 1690c7fd522c0cf459a15909a66e8f8ce6cfb6e9..bd9a1dbe3d50a60f453d194f39ace14d0b961e90 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -sleuthkit-java (4.9.0-1) unstable; urgency=medium +sleuthkit-java (4.10.0-1) unstable; urgency=medium * Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP> diff --git a/debian/sleuthkit-java.install b/debian/sleuthkit-java.install index 9bf890260a185733786c51afbd4b3a0d7f08653d..7def1fbba803358845dc7f5b29ecfe8f2e1fac5e 100644 --- a/debian/sleuthkit-java.install +++ b/debian/sleuthkit-java.install @@ -1,4 +1,4 @@ bindings/java/lib/sqlite-jdbc-3.25.2.jar /usr/share/java -bindings/java/dist/sleuthkit-4.9.0.jar /usr/share/java -case-uco/java/dist/sleuthkit-caseuco-4.9.0.jar /usr/share/java +bindings/java/dist/sleuthkit-4.10.0.jar /usr/share/java +case-uco/java/dist/sleuthkit-caseuco-4.10.0.jar /usr/share/java diff --git a/packages/sleuthkit.spec b/packages/sleuthkit.spec index 4439db52aad80e20aa0f3b0238a2658e46d73294..ede52d5a7ae72ab81aa2c38b813e5f8b47b860da 100644 --- a/packages/sleuthkit.spec +++ b/packages/sleuthkit.spec @@ -1,5 +1,5 @@ Name: sleuthkit -Version: 4.9.0 +Version: 4.10.0 Release: 1%{?dist} Summary: The Sleuth Kit (TSK) is a library and collection of command line tools that allow you to investigate volume and file system data. diff --git a/tsk/Makefile.am b/tsk/Makefile.am index a17d3de69df534508d971bf8548d96bb65ef9ede..a5dd8f2826cd1559a1cc33da0ba37b2958f88c63 100644 --- a/tsk/Makefile.am +++ b/tsk/Makefile.am @@ -8,6 +8,6 @@ libtsk_la_LIBADD = base/libtskbase.la img/libtskimg.la \ vs/libtskvs.la fs/libtskfs.la hashdb/libtskhashdb.la \ auto/libtskauto.la pool/libtskpool.la util/libtskutil.la # current:revision:age -libtsk_la_LDFLAGS = -version-info 20:1:1 $(LIBTSK_LDFLAGS) +libtsk_la_LDFLAGS = -version-info 20:2:1 $(LIBTSK_LDFLAGS) EXTRA_DIST = tsk_tools_i.h docs/Doxyfile docs/*.dox docs/*.html diff --git a/tsk/base/tsk_base.h b/tsk/base/tsk_base.h index 310ec6cc98e049b302861052c37cca7d6832ae59..a94cfa8e8d17a3360ec6237d0eded1e7a1f02a31 100644 --- a/tsk/base/tsk_base.h +++ b/tsk/base/tsk_base.h @@ -39,11 +39,11 @@ * 3.1.2b1 would be 0x03010201. Snapshot from Jan 2, 2003 would be * 0xFF030102. * See TSK_VERSION_STR for string form. */ -#define TSK_VERSION_NUM 0x040900ff +#define TSK_VERSION_NUM 0x041000ff /** Version of code in string form. See TSK_VERSION_NUM for * integer form. */ -#define TSK_VERSION_STR "4.9.0" +#define TSK_VERSION_STR "4.10.0" /* include the TSK-specific header file that we created in autoconf diff --git a/tsk/docs/Doxyfile b/tsk/docs/Doxyfile index cf6380f2c8e7cd4552e12a4e7360b5b61027b26f..ad5b9fb30045a24fc85abb03a06ed68c77d3cd8f 100644 --- a/tsk/docs/Doxyfile +++ b/tsk/docs/Doxyfile @@ -33,7 +33,7 @@ PROJECT_NAME = "The Sleuth Kit" # if some version control system is used. # This is automatically updated at release time. -PROJECT_NUMBER = 4.9.0 +PROJECT_NUMBER = 4.10.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer @@ -883,7 +883,7 @@ GENERATE_HTML = YES # put in front of it. If left blank `html' will be used as the default path. # NOTE: This is automatically updated at release time. -HTML_OUTPUT = api-docs/4.9.0/ +HTML_OUTPUT = api-docs/4.10.0/ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank