Merge pull request #1635 from mhmdfy/multi-sig-mime-type

Multi sig mime type
This commit is contained in:
Richard Cordovano 2015-11-03 10:16:56 -05:00
commit 5f5944098d
5 changed files with 201 additions and 149 deletions

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.modules.filetypeid;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
@ -104,6 +105,29 @@ class FileType {
return interestingFilesSetName;
}
@Override
public String toString() {
return this.mimeType;
}
@Override
public boolean equals(Object other) {
if(other != null && other instanceof FileType) {
FileType that = (FileType) other;
if(this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature()))
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + Objects.hashCode(this.mimeType);
hash = 67 * hash + Objects.hashCode(this.signature);
return hash;
}
/**
* A file signature consisting of a sequence of bytes at a specific offset
* within a file.
@ -221,6 +245,27 @@ 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())
&& this.getOffset() == that.getOffset()
&& this.getType().equals(that.getType()))
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Arrays.hashCode(this.signatureBytes);
hash = 97 * hash + (int) (this.offset ^ (this.offset >>> 32));
hash = 97 * hash + Objects.hashCode(this.type);
return hash;
}
}
}

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.modules.filetypeid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import org.apache.tika.Tika;
@ -38,15 +39,14 @@ public class FileTypeDetector {
private static final Tika tika = new Tika();
private static final int BUFFER_SIZE = 64 * 1024;
private final byte buffer[] = new byte[BUFFER_SIZE];
private final Map<String, FileType> userDefinedFileTypes;
private final List<FileType> userDefinedFileTypes;
/**
* Constructs an object that detects the type of a file by an inspection of
* its contents.
*
* @throws FileTypeDetector.FileTypeDetectorInitException if an
* initialization
* error occurs.
* initialization error occurs.
*/
public FileTypeDetector() throws FileTypeDetectorInitException {
try {
@ -77,7 +77,12 @@ public class FileTypeDetector {
* @return True if MIME type is detectable.
*/
private boolean isDetectableAsUserDefinedType(String mimeType) {
return userDefinedFileTypes.containsKey(mimeType);
for (FileType fileType : userDefinedFileTypes) {
if (fileType.getMimeType().equals(mimeType)) {
return true;
}
}
return false;
}
/**
@ -216,7 +221,7 @@ public class FileTypeDetector {
* @throws TskCoreException
*/
private String detectUserDefinedType(AbstractFile file) throws TskCoreException {
for (FileType fileType : userDefinedFileTypes.values()) {
for (FileType fileType : userDefinedFileTypes) {
if (fileType.matches(file)) {
if (fileType.alertOnMatch()) {
BlackboardArtifact artifact;

View File

@ -31,6 +31,8 @@
<Component id="ingestRunningWarningLabel" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
@ -82,10 +84,7 @@
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
@ -181,7 +180,7 @@
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;FileType&gt;"/>
</AuxValues>
</Component>
</SubComponents>

View File

@ -58,8 +58,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
* the MIME types to file type objects lies behind the list model. This map
* is obtained from the user-defined types manager.
*/
private DefaultListModel<String> typesListModel;
private Map<String, FileType> fileTypes;
private DefaultListModel<FileType> typesListModel;
private java.util.List<FileType> fileTypes;
/**
* This panel implements a property change listener that listens to ingest
@ -227,7 +227,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
ex.getLocalizedMessage(),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title"),
JOptionPane.ERROR_MESSAGE);
fileTypes = Collections.emptyMap();
fileTypes = Collections.emptyList();
}
enableButtons();
}
@ -236,11 +236,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
* Sets the list model for the file types list component.
*/
private void updateFileTypesListModel() {
ArrayList<String> mimeTypes = new ArrayList<>(fileTypes.keySet());
Collections.sort(mimeTypes);
typesListModel.clear();
for (String mimeType : mimeTypes) {
typesListModel.addElement(mimeType);
for (FileType fileType : fileTypes) {
typesListModel.addElement(fileType);
}
}
@ -249,10 +248,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
* panel based on the current selection in the file types list.
*/
private void populateTypeDetailsComponents() {
String mimeType = typesList.getSelectedValue();
FileType fileType = fileTypes.get(mimeType);
FileType fileType = typesList.getSelectedValue();
if (null != fileType) {
mimeTypeTextField.setText(fileType.getMimeType());
mimeTypeTextField.setEditable(false);
Signature signature = fileType.getSignature();
FileType.Signature.Type sigType = signature.getType();
signatureTypeComboBox.setSelectedItem(sigType == FileType.Signature.Type.RAW ? FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
@ -286,6 +285,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private void clearTypeDetailsComponents() {
typesList.clearSelection();
mimeTypeTextField.setText(""); //NON-NLS
mimeTypeTextField.setEditable(true);
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
hexPrefixLabel.setVisible(true);
signatureTextField.setText("0000"); //NON-NLS
@ -339,7 +339,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private void initComponents() {
typesScrollPane = new javax.swing.JScrollPane();
typesList = new javax.swing.JList<String>();
typesList = new javax.swing.JList<FileType>();
separator = new javax.swing.JSeparator();
mimeTypeLabel = new javax.swing.JLabel();
mimeTypeTextField = new javax.swing.JTextField();
@ -449,6 +449,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGroup(layout.createSequentialGroup()
.addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(30, 30, 30))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2)
@ -489,10 +491,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(saveTypeButton)
.addGap(8, 8, 8)))
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(8, 8, 8))))
.addComponent(jLabel1)
.addComponent(jLabel3))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
@ -557,8 +556,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
}//GEN-LAST:event_newTypeButtonActionPerformed
private void deleteTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTypeButtonActionPerformed
String typeName = typesList.getSelectedValue();
fileTypes.remove(typeName);
FileType fileType = typesList.getSelectedValue();
fileTypes.remove(fileType);
updateFileTypesListModel();
if (!typesListModel.isEmpty()) {
typesList.setSelectedIndex(0);
@ -626,7 +625,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
/**
* Get the interesting files set details.
*/
String filesSetName = filesSetNameTextField.getText();
String filesSetName = "";
if (postHitCheckBox.isSelected()) {
filesSetName = filesSetNameTextField.getText();
}
if (postHitCheckBox.isSelected() && filesSetName.isEmpty()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message"),
@ -640,9 +642,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
*/
FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType);
FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected());
fileTypes.put(typeName, fileType);
FileType selected = typesList.getSelectedValue();
if (selected != null) {
fileTypes.remove(selected);
}
fileTypes.add(fileType);
updateFileTypesListModel();
typesList.setSelectedValue(fileType.getMimeType(), true);
typesList.setSelectedValue(fileType, true);
}//GEN-LAST:event_saveTypeButtonActionPerformed
private void postHitCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postHitCheckBoxActionPerformed
@ -685,7 +691,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private javax.swing.JTextField signatureTextField;
private javax.swing.JComboBox<String> signatureTypeComboBox;
private javax.swing.JLabel signatureTypeLabel;
private javax.swing.JList<String> typesList;
private javax.swing.JList<FileType> typesList;
private javax.swing.JScrollPane typesScrollPane;
// End of variables declaration//GEN-END:variables

View File

@ -25,10 +25,7 @@ import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
@ -82,7 +79,7 @@ final class UserDefinedFileTypesManager {
* map is guarded by the intrinsic lock of the user-defined file types
* manager for thread-safety.
*/
private final Map<String, FileType> userDefinedFileTypes = new HashMap<>();
private final List<FileType> userDefinedFileTypes = new ArrayList<>();
/**
* The combined set of user-defined file types and file types predefined by
@ -91,7 +88,7 @@ final class UserDefinedFileTypesManager {
* the intrinsic lock of the user-defined file types manager for
* thread-safety.
*/
private final Map<String, FileType> fileTypes = new HashMap<>();
private final List<FileType> fileTypes = new ArrayList<>();
/**
* Gets the singleton manager of user-defined file types characterized by
@ -122,7 +119,7 @@ final class UserDefinedFileTypesManager {
* @throws
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
*/
synchronized Map<String, FileType> getFileTypes() throws UserDefinedFileTypesException {
synchronized List<FileType> getFileTypes() throws UserDefinedFileTypesException {
loadFileTypes();
/**
@ -131,7 +128,7 @@ final class UserDefinedFileTypesManager {
* Collections.unmodifiableCollection() is not used here because this
* view of the file types is a snapshot.
*/
return new HashMap<>(fileTypes);
return new ArrayList<>(fileTypes);
}
/**
@ -142,7 +139,7 @@ final class UserDefinedFileTypesManager {
* @throws
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
*/
synchronized Map<String, FileType> getUserDefinedFileTypes() throws UserDefinedFileTypesException {
synchronized List<FileType> getUserDefinedFileTypes() throws UserDefinedFileTypesException {
loadFileTypes();
/**
@ -151,7 +148,7 @@ final class UserDefinedFileTypesManager {
* Collections.unmodifiableCollection() is not used here because this
* view of the file types is a snapshot.
*/
return new HashMap<>(userDefinedFileTypes);
return new ArrayList<>(userDefinedFileTypes);
}
/**
@ -186,44 +183,44 @@ final class UserDefinedFileTypesManager {
try {
// Add rule for xml
fileType = new FileType("text/xml", new Signature("<?xml", 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for gzip
byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS
fileType = new FileType("application/x-gzip", new Signature(byteArray, 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .wk1
byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS
fileType = new FileType("application/x-123", new Signature(byteArray, 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for Radiance image
byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS
fileType = new FileType("image/vnd.radiance", new Signature(byteArray, 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .dcx image
byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS
fileType = new FileType("image/x-dcx", new Signature(byteArray, 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .ics image
fileType = new FileType("image/x-icns", new Signature("icns", 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .pict image
byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS
fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .pam
fileType = new FileType("image/x-portable-arbitrarymap", new Signature("P7", 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
// Add rule for .pfm
fileType = new FileType("image/x-portable-floatmap", new Signature("PF", 0L), "", false); //NON-NLS
fileTypes.put(fileType.getMimeType(), fileType);
fileTypes.add(fileType);
}
// parseHexBinary() throws this if the argument passed in is not Hex
catch (IllegalArgumentException e) {
@ -265,8 +262,8 @@ final class UserDefinedFileTypesManager {
* @param fileType The file type to add.
*/
private void addUserDefinedFileType(FileType fileType) {
userDefinedFileTypes.put(fileType.getMimeType(), fileType);
fileTypes.put(fileType.getMimeType(), fileType);
userDefinedFileTypes.add(fileType);
fileTypes.add(fileType);
}
/**
@ -275,10 +272,10 @@ final class UserDefinedFileTypesManager {
* @param newFileTypes A mapping of file type names to user-defined file
* types.
*/
synchronized void setUserDefinedFileTypes(Map<String, FileType> newFileTypes) throws UserDefinedFileTypesException {
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
try {
String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_DEFINITIONS_FILE);
XmlWriter.writeFileTypes(newFileTypes.values(), filePath);
XmlWriter.writeFileTypes(newFileTypes, filePath);
} catch (ParserConfigurationException | FileNotFoundException | UnsupportedEncodingException | TransformerException ex) {
throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.saveFileTypes.errorMessage");
} catch (IOException ex) {
@ -316,7 +313,7 @@ final class UserDefinedFileTypesManager {
* @throws UnsupportedEncodingException
* @throws TransformerException
*/
private static void writeFileTypes(Collection<FileType> fileTypes, String filePath) throws ParserConfigurationException, IOException, FileNotFoundException, UnsupportedEncodingException, TransformerException {
private static void writeFileTypes(List<FileType> fileTypes, String filePath) throws ParserConfigurationException, IOException, FileNotFoundException, UnsupportedEncodingException, TransformerException {
Document doc = XMLUtil.createDocument();
Element fileTypesElem = doc.createElement(FILE_TYPES_TAG_NAME);
doc.appendChild(fileTypesElem);