Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve stability and extend feature set to AFF4 1.1 #7

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
dfbed78
Improve resource id parsing, trim whitespace and trailing '/' from ARNs.
Jun 2, 2022
1231987
Resolve failing blank.aff4 and blank5.aff4 test cases.
Jun 2, 2022
2f03eef
Upgrade build and source dependencies, move to Java 11 LTS.
Jun 3, 2022
558aff7
Resolve build warning: slf4j-log4j12 has been relocated to slf4j-relo…
Jun 3, 2022
5e4a459
Introduce AFF4-L lexicon.
Jun 3, 2022
b0706e5
Handle malformed images with invalid XSD typename: datetime.
Jun 3, 2022
9490f35
Exposed date-time (ISO 8601) parsing via AFF4Resource.
Jun 3, 2022
c10f214
Add logical image details to AFF4Image instances, if present.
Jun 3, 2022
51d3922
Enable version 1.1 containers.
Jun 3, 2022
03111ff
Removed 'No Map aff4:dataStream defined for Image.' warning, no dataS…
Jun 3, 2022
249cc5f
Updated Information extraction example for AFF4 1.1 images.
Jun 3, 2022
6aaf1fe
Updated Information extraction example to print ImageStream details f…
Jun 3, 2022
d320313
Drop logic to remove trail '/' from ARNs, keep trim whitespace.
Jun 3, 2022
2d186ee
Fix AFF4ZipContainer method name setPropety to setProperty.
Jun 6, 2022
46b752e
Move AFF4ZipContainer.sanitizeResource to NameCodec.SanitizeResource.
Jun 6, 2022
c17a948
BevvyIndex sanitized chunk-name and chunk-index zip entry discovery.
Jun 6, 2022
e306866
Add ZipFileSegement lexicon.
Jun 7, 2022
98f1692
Resolve data hygiene issue around zip entry names; different tools, d…
Jun 7, 2022
7f58140
More data hygiene issues re:zip entry naming.
Jun 7, 2022
52057da
Minor version number bump 1.0.3 to 1.0.4
Jun 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[1.0.4] 17-Jun-2022
- Support AFF4 1.1 containers

[1.0.3] 5-Jul-2019
- Support MQ custom lexicon items

Expand Down
24 changes: 12 additions & 12 deletions META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Automatic-Module-Name: com.evimetry.aff4
Bundle-ManifestVersion: 2
Bundle-Name: AFF4 Java
Bundle-SymbolicName: com.evimetry.aff4;singleton:=true
Bundle-Version: 1.0.3
Bundle-Version: 1.0.4
Bundle-Vendor: Schatz Forensic
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-Classpath: .
Export-Package: com.evimetry.aff4,
com.evimetry.aff4.codec,
Expand All @@ -19,16 +19,16 @@ Export-Package: com.evimetry.aff4,
com.evimetry.aff4.resolver,
com.evimetry.aff4.resource,
com.evimetry.aff4.struct
Import-Package: com.github.benmanes.caffeine.cache;version="2.7.0",
Import-Package: com.github.benmanes.caffeine.cache;version="3.1.1",
net.jpountz.lz4,
org.apache.commons.compress.archivers.zip;version="1.18.0",
org.apache.commons.io;version="2.6.0",
org.apache.jena;version="3.10.0",
org.apache.jena.datatypes.xsd;version="3.10.0",
org.apache.jena.rdf.model;version="3.10.0",
org.apache.jena.util;version="3.10.0",
org.apache.jena.vocabulary;version="3.10.0",
org.slf4j;version="1.7.2",
org.xerial.snappy;version="1.1.7"
org.apache.commons.compress.archivers.zip;version="1.21",
org.apache.commons.io;version="2.11.0",
org.apache.jena;version="4.5.0",
org.apache.jena.datatypes.xsd;version="4.5.0",
org.apache.jena.rdf.model;version="4.5.0",
org.apache.jena.util;version="4.5.0",
org.apache.jena.vocabulary;version="4.5.0",
org.slf4j;version="1.7.36",
org.xerial.snappy;version="1.1.8.4"


4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
AFF4 Java v1.0.3
AFF4 Java v1.0.4
-----
An AFF4 Standard v1.0 compliant reader library.
An AFF4 Standard v1.1 compliant reader library.

Copyright (c) Schatz Forensic Pty Ltd, 2017-2019

Expand Down
42 changes: 23 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.evimetry.aff4</groupId>
<artifactId>aff4-reader-lite</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
<name>AFF4 Java Reader-lite</name>
<url>https://github.com/aff4/aff4-java/</url>
<organization>
Expand Down Expand Up @@ -48,22 +48,22 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<version>3.0.0-M6</version>
</plugin>
<plugin>
<!-- Build an JAR WITHOUT the maven manifest -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
Expand All @@ -89,13 +89,13 @@
</execution>
</executions>
<configuration>
<additionalparam>-quiet -Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
Expand All @@ -116,55 +116,59 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>3.0.0-M3</version>
<version>3.0.0-M6</version>
</plugin>
</plugins>
</reporting>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
<artifactId>slf4j-reload4j</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.7.3</version>
<version>1.1.8.4</version>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.6.0</version>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
<version>3.11.0</version>
<version>4.4.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.7.0</version>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
<version>1.21</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<inceptionYear>2017</inceptionYear>
</project>
Expand Down
63 changes: 62 additions & 1 deletion src/main/java/com/evimetry/aff4/AFF4Lexicon.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public enum AFF4Lexicon {
* Base type for AFF4 Zip64-based containers.
*/
ZipVolume(AFF4.AFF4_BASE_URI + "ZipVolume"),

/**
* ZipFileSegment is an AFF4 object representing a single member of the zip file.
*/
ZipFileSegment(AFF4.AFF4_BASE_URI + "zip_segment"),

/**
* The creation time of the volume.
Expand Down Expand Up @@ -328,7 +333,63 @@ public enum AFF4Lexicon {
/**
* Volume/Disk contains unallocated regions (sparse).
*/
ContainsUnallocated(AFF4.BBT_BASE_URI + "ContainsUnallocated");
ContainsUnallocated(AFF4.BBT_BASE_URI + "ContainsUnallocated"),

/* AFF4-L Properties */
/**
* The original unencoded file path and name of a logical evidence object.
*/
originalFileName(AFF4.AFF4_BASE_URI + "originalFileName"),

/**
* The birth time of a file's content and metadata.
*/
birthTime(AFF4.AFF4_BASE_URI + "birthTime"),

/**
* The last modified time of a file's content.
*/
lastWritten(AFF4.AFF4_BASE_URI + "lastWritten"),

/**
* The last modified time of a file's filesystem metadata.
*/
recordChanged(AFF4.AFF4_BASE_URI + "recordChanged"),

/**
* The last access time of a file's content.
*/
lastAccessed(AFF4.AFF4_BASE_URI + "lastAccessed"),

/**
* Folder Class representing a suspect folder.
*/
Folder(AFF4.AFF4_BASE_URI + "Folder"),

/**
* Folder Class representing a suspect folder.
*/
FolderImage(AFF4.AFF4_BASE_URI + "FolderImage"),

/**
* FileImage Class representing a suspect file.
*/
FileImage(AFF4.AFF4_BASE_URI + "FileImage"),

/**
* Property representing the FilesImages contained in a Folder.
*/
FilesImages(AFF4.AFF4_BASE_URI + "FilesImages"),

/**
* Class representing a logical acquisition activity.
*/
LogicalAcquisitionTask(AFF4.AFF4_BASE_URI + "LogicalAcquisitionTask"),

/**
* Property pointing to a Folder or FileImage which forms the root of an acquisition operation.
*/
FilesystemRoot(AFF4.AFF4_BASE_URI + "filesystemRoot");

/**
* Map of all values to activities.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/evimetry/aff4/Containers.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private static IAFF4Container openContainer(File file) throws IOException {
}

String resourceID = getResourceID(file);
if (resourceID == null || resourceID.trim().isEmpty()) {
if (resourceID == null || resourceID.isEmpty()) {
throw new IOException("File does not appear to be an AFF4 File.");
}
try {
Expand Down Expand Up @@ -151,7 +151,7 @@ public static String getResourceID(File file) {
logger.error(e.getMessage(), e);
}

return resourceID;
return (resourceID == null) ? null : resourceID.trim();
}

/**
Expand Down
51 changes: 21 additions & 30 deletions src/main/java/com/evimetry/aff4/container/AFF4ZipContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ private void loadVersionInformation() throws ZipException, IOException {
try (InputStream stream = zip.getInputStream(entry)) {
Properties prop = new Properties();
prop.load(stream);
setPropety(prop, "tool", AFF4Lexicon.Tool);
setPropety(prop, "major", AFF4Lexicon.majorVersion);
setPropety(prop, "minor", AFF4Lexicon.minorVersion);
setProperty(prop, "tool", AFF4Lexicon.Tool);
setProperty(prop, "major", AFF4Lexicon.majorVersion);
setProperty(prop, "minor", AFF4Lexicon.minorVersion);
if(!checkSupportedVersion()) {
try {
close();
Expand All @@ -172,7 +172,7 @@ private void loadVersionInformation() throws ZipException, IOException {
* @param property The property to enquire
* @param key The key to use to insert into the main properties.
*/
private void setPropety(Properties input, String property, AFF4Lexicon key) {
private void setProperty(Properties input, String property, AFF4Lexicon key) {
String v = input.getProperty(property);
if (v != null) {
this.properties.put(key, Collections.singletonList(v));
Expand Down Expand Up @@ -223,7 +223,7 @@ private boolean checkSupportedVersion() throws IOException {
try {
long maj = Long.parseLong(major.iterator().next().toString());
long min = Long.parseLong(minor.iterator().next().toString());
return (maj == 1 && min == 0);
return maj == 1 && (min == 0 || min == 1);
} catch (NumberFormatException e) {
// Ignore.
logger.warn(e.getMessage(), e);
Expand Down Expand Up @@ -365,8 +365,15 @@ public Model getModel() {
*/
public IAFF4ImageStream getSegment(String resource) throws IOException {
// Strip any leading URI for this container.
String res = sanitizeResource(resource);
String res = NameCodec.SanitizeResource(resource, getResourceID());
ZipArchiveEntry entry = zip.getEntry(res);
// Some AFF4 tools strip leading '/' characters from the
// entity name, others leave it in. Same goes for trailing
// '/' characters on ARNs.
if (entry == null) {
entry = zip.getEntry("/" + res);
}

if (entry != null) {
if (entry.getMethod() != ZipMethod.STORED.getCode()) {
if (entry.getSize() < ZipSegmentImageCompressedStream.MAX_BUFFER_SIZE) {
Expand Down Expand Up @@ -421,8 +428,15 @@ public IAFF4ImageStream getImageStream(String resource) throws IOException {
}
} else {
// Check for index file.
String res = sanitizeResource(resource + "/00000000.index");
String res = NameCodec.SanitizeResource(resource + "/00000000.index", getResourceID());
ZipArchiveEntry entry = zip.getEntry(res);
// Some AFF4 tools strip leading '/' characters from the
// entity name, others leave it in. Same goes for trailing
// '/' characters on ARNs.
if (entry == null) {
entry = zip.getEntry("/" + res);
}

if (entry != null) {
// This is us!
IAFF4ImageStream stream = new AFF4ImageStream(resource, this, zip, channel, model);
Expand Down Expand Up @@ -470,29 +484,6 @@ public IAFF4Image getImage(String resource) throws IOException {
return null;
}

/**
* Attempt to sanitise the given resource string
*
* @param res The resource string to sanitise
* @return The sanitised resource string.
*/
private String sanitizeResource(String res) {
// strip any leading "/"
while (res.startsWith("/")) {
res = res.substring(1);
}
if (res.startsWith(getResourceID())) {
res = res.substring(getResourceID().length());
}
// Convert any "aff4://" characters to "aff4%3A%2F%2F"
res = NameCodec.encode(res);
// strip any leading "/"
while (res.startsWith("/")) {
res = res.substring(1);
}
return res;
}

/**
* Notify this container that the ZipImageStream has been closed.
*
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/evimetry/aff4/image/AFF4Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ private void initProperties(Model model) {
addStringProperty(model, getResourceID(), AFF4Lexicon.acquisitionType);
addResourceProperty(model, getResourceID(), AFF4Lexicon.dataStream);
addResourceProperty(model, getResourceID(), AFF4Lexicon.dependentStream);

// Logical image details
addDateTimeProperty(model, getResourceID(), AFF4Lexicon.birthTime);
addDateTimeProperty(model, getResourceID(), AFF4Lexicon.lastAccessed);
addDateTimeProperty(model, getResourceID(), AFF4Lexicon.lastWritten);
addDateTimeProperty(model, getResourceID(), AFF4Lexicon.recordChanged);
addStringProperty(model, getResourceID(), AFF4Lexicon.originalFileName);

// Is disk or memory image?
if (properties.get(AFF4Lexicon.RDFType).contains(AFF4Lexicon.MemoryImage)) {
// Memory
Expand Down Expand Up @@ -121,7 +129,7 @@ public IAFF4Map getMap() {
// we are also a aff4:Map
return new AFF4Map(getResourceID(), getResourceID(), parent, model);
}
logger.warn("No Map aff4:dataStream defined for Image " + getResourceID());

return null;
}

Expand Down
Loading