diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 4f7f0bd043..432b4934e0 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.modules.filetypeid; +import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; @@ -31,8 +32,9 @@ import org.sleuthkit.datamodel.TskCoreException; *

* Thread-safe (immutable). */ -class FileType { +class FileType implements Serializable { + private static final long serialVersionUID = 1L; private final String mimeType; private final Signature signature; private final String interestingFilesSetName; @@ -104,19 +106,20 @@ class FileType { String getFilesSetName() { return interestingFilesSetName; } - + @Override public String toString() { return this.mimeType; } - + @Override public boolean equals(Object other) { - if(other != null && other instanceof FileType) { + if (other != null && other instanceof FileType) { FileType that = (FileType) other; - if(this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature())) + if (this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature())) { return true; - } + } + } return false; } @@ -134,14 +137,16 @@ class FileType { *

* Thread-safe (immutable). */ - static class Signature { - + static class Signature implements Serializable { + + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(Signature.class.getName()); /** * The way the signature byte sequence should be interpreted. */ enum Type { + RAW, ASCII }; @@ -156,8 +161,8 @@ class FileType { * * @param signatureBytes The signature bytes. * @param offset The offset of the signature bytes. - * @param type The type of data in the byte array. Impacts - * how it is displayed to the user in the UI. + * @param type The type of data in the byte array. Impacts how + * it is displayed to the user in the UI. */ Signature(final byte[] signatureBytes, long offset, Type type) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -165,13 +170,13 @@ class FileType { this.type = type; this.isRelativeToStart = true; } - + /** - * Creates a file signature consisting of an ASCII string at a - * specific offset within a file. + * Creates a file signature consisting of an ASCII string at a specific + * offset within a file. * * @param signatureString The ASCII string - * @param offset The offset of the signature bytes. + * @param offset The offset of the signature bytes. */ Signature(String signatureString, long offset) { this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); @@ -179,12 +184,12 @@ class FileType { this.type = Type.ASCII; this.isRelativeToStart = true; } - + /** * Creates a file signature consisting of a sequence of bytes at a - * specific offset within a file. If bytes correspond to an ASCII - * string, use one of the other constructors so that the string is - * displayed to the user instead of the raw bytes. + * specific offset within a file. If bytes correspond to an ASCII + * string, use one of the other constructors so that the string is + * displayed to the user instead of the raw bytes. * * @param signatureBytes The signature bytes. * @param offset The offset of the signature bytes. @@ -195,16 +200,17 @@ class FileType { this.type = Type.RAW; this.isRelativeToStart = true; } - + /** * Creates a file signature consisting of a sequence of bytes at a * specific offset within a file. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. - * @param type The type of data in the byte array. Impacts - * how it is displayed to the user in the UI. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureBytes The signature bytes. + * @param offset The offset of the signature bytes. + * @param type The type of data in the byte array. Impacts + * how it is displayed to the user in the UI. + * @param isRelativeToStart Determines whether this signature is + * relative to start. */ Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -212,14 +218,15 @@ class FileType { this.type = type; this.isRelativeToStart = isRelativeToStart; } - + /** - * Creates a file signature consisting of an ASCII string at a - * specific offset within a file. + * Creates a file signature consisting of an ASCII string at a specific + * offset within a file. * - * @param signatureString The ASCII string - * @param offset The offset of the signature bytes. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureString The ASCII string + * @param offset The offset of the signature bytes. + * @param isRelativeToStart Determines whether this signature is + * relative to start. */ Signature(String signatureString, long offset, boolean isRelativeToStart) { this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); @@ -227,16 +234,17 @@ class FileType { this.type = Type.ASCII; this.isRelativeToStart = isRelativeToStart; } - + /** * Creates a file signature consisting of a sequence of bytes at a - * specific offset within a file. If bytes correspond to an ASCII - * string, use one of the other constructors so that the string is - * displayed to the user instead of the raw bytes. + * specific offset within a file. If bytes correspond to an ASCII + * string, use one of the other constructors so that the string is + * displayed to the user instead of the raw bytes. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureBytes The signature bytes. + * @param offset The offset of the signature bytes. + * @param isRelativeToStart Determines whether this signature is + * relative to start. */ Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -271,7 +279,7 @@ class FileType { Type getType() { return type; } - + boolean isRelativeToStart() { return isRelativeToStart; } @@ -285,12 +293,13 @@ class FileType { * @return True or false. */ boolean containedIn(final AbstractFile file) { - if(offset >= file.getSize()) { + if (offset >= file.getSize()) { return false; // File is too small, offset lies outside file. } long actualOffset = offset; - if(!isRelativeToStart) + if (!isRelativeToStart) { actualOffset = file.getSize() - 1 - offset; + } if (file.getSize() < (actualOffset + signatureBytes.length)) { return false; /// too small, can't contain this signature } @@ -308,15 +317,16 @@ class FileType { return false; } } - + @Override public boolean equals(Object other) { if (other != null && other instanceof Signature) { Signature that = (Signature) other; - if(Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes()) + if (Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes()) && this.getOffset() == that.getOffset() - && this.getType().equals(that.getType())) + && this.getType().equals(that.getType())) { return true; + } } return false; } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index 8f2dbaabca..a6d0a1e992 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -19,7 +19,9 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.file.Path; @@ -27,6 +29,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; +import javax.persistence.PersistenceException; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -34,10 +37,13 @@ import org.w3c.dom.NodeList; import javax.xml.bind.DatatypeConverter; import javax.xml.transform.TransformerException; import org.openide.util.NbBundle; +import org.openide.util.io.NbObjectInputStream; +import org.openide.util.io.NbObjectOutputStream; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; +import org.sleuthkit.datamodel.TskCoreException; import org.w3c.dom.Node; import org.xml.sax.SAXException; @@ -60,6 +66,7 @@ final class UserDefinedFileTypesManager { private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName()); private static final String USER_DEFINED_TYPE_DEFINITIONS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS + private static final String USER_DEFINED_TYPE_SERIALIZATION_FILE = "UserFileTypeDefinitions.settings"; private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS @@ -323,14 +330,16 @@ final class UserDefinedFileTypesManager { * @throws TransformerException */ private static void writeFileTypes(List fileTypes, String filePath) throws ParserConfigurationException, IOException, FileNotFoundException, UnsupportedEncodingException, TransformerException { - Document doc = XMLUtil.createDocument(); - Element fileTypesElem = doc.createElement(FILE_TYPES_TAG_NAME); - doc.appendChild(fileTypesElem); - for (FileType fileType : fileTypes) { - Element fileTypeElem = XmlWriter.createFileTypeElement(fileType, doc); - fileTypesElem.appendChild(fileTypeElem); + try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_SERIALIZATION_FILE)))) { + UserDefinedFileTypesSettings settings = new UserDefinedFileTypesSettings(fileTypes); + out.writeObject(settings); + File xmlFile = new File(filePath); + if (xmlFile.exists()) { + xmlFile.delete(); + } + } catch (IOException ex) { + throw new PersistenceException(String.format("Failed to write settings to %s", getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_SERIALIZATION_FILE)), ex); } - XMLUtil.saveDocument(doc, ENCODING_FOR_XML_FILE, filePath); } /** @@ -457,6 +466,18 @@ final class UserDefinedFileTypesManager { fileTypes.add(fileType); } } + } else { + File serializedDefs = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_SERIALIZATION_FILE)); + if (serializedDefs.exists()) { + try { + try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedDefs))) { + UserDefinedFileTypesSettings filesSetsSettings = (UserDefinedFileTypesSettings) in.readObject(); + return filesSetsSettings.getUserDefinedFileTypes(); + } + } catch (IOException | ClassNotFoundException ex) { + throw new PersistenceException(String.format("Failed to read settings from %s", getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_SERIALIZATION_FILE)), ex); + } + } } return fileTypes; } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesSettings.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesSettings.java new file mode 100755 index 0000000000..e2a3e8e348 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesSettings.java @@ -0,0 +1,32 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.modules.filetypeid; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author oliver + */ +class UserDefinedFileTypesSettings implements Serializable { + private static final long serialVersionUID = 1L; + private List userDefinedFileTypes; + + UserDefinedFileTypesSettings(List userDefinedFileTypes) { + this.userDefinedFileTypes = userDefinedFileTypes; + } + + /** + * @return the userDefinedFileTypes + */ + public List getUserDefinedFileTypes() { + return userDefinedFileTypes; + } + + +}