Merge remote-tracking branch 'upstream/develop' into aut-2034

This commit is contained in:
Oliver Spohngellert 2016-04-18 12:21:53 -04:00
commit 8cbbd00d15
12 changed files with 1618 additions and 690 deletions

View File

@ -0,0 +1,196 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.filetypeid;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
/**
* A dialog box that allows a user to create a file type signature, to be added
* to a selected file type.
*/
final class AddFileTypeSignatureDialog extends JDialog {
private static final long serialVersionUID = 1L;
private final AddFileTypeSignaturePanel addFileTypeSigPanel;
private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text");
private Signature signature;
private BUTTON_PRESSED result;
/**
* Enum used for letting creator of this dialog know whether or not OK was
* pressed.
*/
enum BUTTON_PRESSED {
OK, CANCEL;
}
/**
* Creates a file type signature dialog for a new signature.
*/
AddFileTypeSignatureDialog() {
super(new JFrame(TITLE), TITLE, true);
this.addFileTypeSigPanel = new AddFileTypeSignaturePanel();
this.display(true);
}
/**
* Creates a file type signature dialog for a signature being edited.
*
* @param toEdit The signature to edit.
*/
AddFileTypeSignatureDialog(Signature toEdit) {
super(new JFrame(TITLE), TITLE, true);
this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(toEdit);
this.display(false);
}
/**
* Gets the signature that was created by this dialog.
*
* @return the signature.
*/
public Signature getSignature() {
return signature;
}
/**
* Gets which button was pressed (OK or Cancel).
*
* @return The result.
*/
public BUTTON_PRESSED getResult() {
return result;
}
/**
* Displays the add signature dialog.
*
* @param add Whether or not this is an edit or a new window.
*/
@Messages({
"AddFileTypeSignatureDialog.addButton.title=Add",
"AddFileTypeSignatureDialog.addButton.title2=Done",
"AddFileTypeSignatureDialog.cancelButton.title=Cancel"})
void display(boolean add) {
setLayout(new BorderLayout());
/**
* Center the dialog.
*/
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
int width = this.getSize().width;
int height = this.getSize().height;
setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2);
/**
* Get the default or saved ingest job settings for this context and use
* them to create and add an ingest job settings panel.
*/
add(this.addFileTypeSigPanel, BorderLayout.PAGE_START);
// Add the add/done button.
JButton addButton;
if (add) {
addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title());
} else {
addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title2());
}
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doButtonAction(true);
}
});
// Add a close button.
JButton closeButton = new JButton(Bundle.AddFileTypeSignatureDialog_cancelButton_title());
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doButtonAction(false);
}
});
// Put the buttons in their own panel, under the settings panel.
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
buttonPanel.add(addButton);
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
buttonPanel.add(closeButton);
add(buttonPanel, BorderLayout.LINE_START);
/**
* Add a handler for when the dialog window is closed directly,
* bypassing the buttons.
*/
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
doButtonAction(false);
}
});
/**
* Show the dialog.
*/
pack();
setResizable(false);
setVisible(true);
}
/**
* Performs actions on the fields based on whether the ok button was pressed
* or not.
*
* @param okPressed Whether ok was pressed.
*/
@Messages({"AddFileTypeSignatureDialog.invalidSignature.message=Invalid signature"})
private void doButtonAction(boolean okPressed) {
if (okPressed) {
Signature sig = addFileTypeSigPanel.getSignature();
if (sig != null) {
this.signature = sig;
this.result = BUTTON_PRESSED.OK;
setVisible(false);
}
} else {
this.signature = null;
this.result = BUTTON_PRESSED.CANCEL;
setVisible(false);
}
}
}

View File

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="signatureTypeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="signatureTypeComboBox" min="-2" pref="176" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="signatureLabel" min="-2" pref="73" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="hexPrefixLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="signatureTextField" min="-2" pref="160" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="offsetLabel" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="offsetTextField" min="-2" pref="178" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="offsetRelativeToLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="offsetRelativeToComboBox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="26" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="signatureTypeComboBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="signatureTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
<Component id="hexPrefixLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="signatureTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="signatureLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="offsetLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="offsetTextField" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="offsetRelativeToComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="offsetRelativeToLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="offsetLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.offsetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="offsetTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetTextField" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.offsetTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="offsetRelativeToComboBox">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetRelativeToComboBox" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="offsetRelativeToLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetRelativeToLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.offsetRelativeToLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="hexPrefixLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="hexPrefixLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.hexPrefixLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="signatureTypeComboBox">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTypeComboBox" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="signatureTypeComboBoxActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="signatureLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.signatureLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="signatureTypeLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTypeLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.signatureTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="signatureTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTextField" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="AddFileTypeSignaturePanel.signatureTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="signatureTextFieldActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,325 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.filetypeid;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.xml.bind.DatatypeConverter;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
/**
* Panel for creating a file type signature to be added to a file type.
*/
class AddFileTypeSignaturePanel extends javax.swing.JPanel {
private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem");
private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem");
private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem");
private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem");
/**
* Creates a panel for a new signature.
*/
AddFileTypeSignaturePanel() {
initComponents();
customizeComponents();
}
/**
* Creates a panel for a signature being edited.
*
* @param toEdit The signature to edit.
*/
AddFileTypeSignaturePanel(Signature toEdit) {
this();
this.setComponentValues(toEdit);
}
/**
* Configures the components of the panel correctly.
*/
private void customizeComponents() {
setSignatureTypeComboBoxModel();
setOffsetRealtiveToComboBoxModel();
}
/**
* Sets the model for the signature type combo box.
*/
private void setSignatureTypeComboBoxModel() {
DefaultComboBoxModel<String> sigTypeComboBoxModel = new DefaultComboBoxModel<>();
sigTypeComboBoxModel.addElement(RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
sigTypeComboBoxModel.addElement(ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
signatureTypeComboBox.setModel(sigTypeComboBoxModel);
signatureTypeComboBox.setSelectedItem(RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
}
/**
* Sets the model for the signature type combo box.
*/
private void setOffsetRealtiveToComboBoxModel() {
DefaultComboBoxModel<String> offsetRelComboBoxModel = new DefaultComboBoxModel<>();
offsetRelComboBoxModel.addElement(START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetRelComboBoxModel.addElement(END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetRelativeToComboBox.setModel(offsetRelComboBoxModel);
offsetRelativeToComboBox.setSelectedItem(START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
}
/**
* Sets the values for the components based on the signature being edited.
*
* @param toEdit The signature information to implement.
*/
@Messages({"AddFileTypeSignaturePanel.signatureStringFail.text=Couldn't get signatures string"})
private void setComponentValues(Signature toEdit) {
if (toEdit.isRelativeToStart()) {
this.offsetRelativeToComboBox.setSelectedIndex(0);
} else {
this.offsetRelativeToComboBox.setSelectedIndex(1);
}
this.offsetTextField.setText(toEdit.getOffset() + "");
if (Signature.Type.RAW == toEdit.getType()) {
this.signatureTypeComboBox.setSelectedIndex(0);
this.signatureTextField.setText(DatatypeConverter.printHexBinary(toEdit.getSignatureBytes()));
} else {
this.signatureTypeComboBox.setSelectedIndex(1);
try {
this.signatureTextField.setText(new String(toEdit.getSignatureBytes(), "UTF-8"));
} catch (UnsupportedEncodingException ex) {
JOptionPane.showMessageDialog(null,
ex.getLocalizedMessage(),
Bundle.AddFileTypeSignaturePanel_signatureStringFail_text(),
JOptionPane.ERROR_MESSAGE);
}
}
}
/**
* Gets the file type signature for this panel, pops up error windows if the
* signature is incomplete.
*
* @return The signature of this panel, or null if it is an invalid
* signature.
*/
public Signature getSignature() {
/**
* Get the signature type.
*/
FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII;
/**
* Get the signature bytes.
*/
String sigString = signatureTextField.getText();
if (sigString.isEmpty()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title"),
JOptionPane.ERROR_MESSAGE);
return null;
}
byte[] signatureBytes;
if (FileType.Signature.Type.RAW == sigType) {
try {
sigString = sigString.replaceAll("\\s", ""); //NON-NLS
signatureBytes = DatatypeConverter.parseHexBinary(sigString);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"),
JOptionPane.ERROR_MESSAGE);
return null;
}
} else {
signatureBytes = sigString.getBytes(Charset.forName("UTF-8"));
}
/**
* Get the offset.
*/
long offset;
boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == START_OFFSET_RELATIVE_COMBO_BOX_ITEM;
try {
offset = Long.parseUnsignedLong(offsetTextField.getText());
if (!isRelativeToStart && signatureBytes.length > offset + 1) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"),
JOptionPane.ERROR_MESSAGE);
return null;
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"),
JOptionPane.ERROR_MESSAGE);
return null;
}
/**
* Get the interesting files set details.
*/
/**
* Put it all together and reset the file types list component.
*/
FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart);
return signature;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
offsetLabel = new javax.swing.JLabel();
offsetTextField = new javax.swing.JTextField();
offsetRelativeToComboBox = new javax.swing.JComboBox<String>();
offsetRelativeToLabel = new javax.swing.JLabel();
hexPrefixLabel = new javax.swing.JLabel();
signatureTypeComboBox = new javax.swing.JComboBox<String>();
signatureLabel = new javax.swing.JLabel();
signatureTypeLabel = new javax.swing.JLabel();
signatureTextField = new javax.swing.JTextField();
offsetLabel.setFont(offsetLabel.getFont().deriveFont(offsetLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(offsetLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetLabel.text")); // NOI18N
offsetTextField.setFont(offsetTextField.getFont().deriveFont(offsetTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
offsetTextField.setText(org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetTextField.text")); // NOI18N
offsetRelativeToComboBox.setFont(offsetRelativeToComboBox.getFont().deriveFont(offsetRelativeToComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
offsetRelativeToLabel.setFont(offsetRelativeToLabel.getFont().deriveFont(offsetRelativeToLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(offsetRelativeToLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetRelativeToLabel.text")); // NOI18N
hexPrefixLabel.setFont(hexPrefixLabel.getFont().deriveFont(hexPrefixLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.hexPrefixLabel.text")); // NOI18N
signatureTypeComboBox.setFont(signatureTypeComboBox.getFont().deriveFont(signatureTypeComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
signatureTypeComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
signatureTypeComboBoxActionPerformed(evt);
}
});
signatureLabel.setFont(signatureLabel.getFont().deriveFont(signatureLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureLabel.text")); // NOI18N
signatureTypeLabel.setFont(signatureTypeLabel.getFont().deriveFont(signatureTypeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(signatureTypeLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureTypeLabel.text")); // NOI18N
signatureTextField.setFont(signatureTextField.getFont().deriveFont(signatureTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
signatureTextField.setText(org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureTextField.text")); // NOI18N
signatureTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
signatureTextFieldActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(signatureTypeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(hexPrefixLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(offsetRelativeToLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(26, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(signatureTypeLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(hexPrefixLabel)
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(signatureLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(offsetLabel)
.addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(offsetRelativeToLabel))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void signatureTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTypeComboBoxActionPerformed
if (signatureTypeComboBox.getSelectedItem() == RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM) {
hexPrefixLabel.setVisible(true);
signatureTextField.setText("0000");
} else {
hexPrefixLabel.setVisible(false);
signatureTextField.setText("");
}
}//GEN-LAST:event_signatureTypeComboBoxActionPerformed
private void signatureTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_signatureTextFieldActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel hexPrefixLabel;
private javax.swing.JLabel offsetLabel;
private javax.swing.JComboBox<String> offsetRelativeToComboBox;
private javax.swing.JLabel offsetRelativeToLabel;
private javax.swing.JTextField offsetTextField;
private javax.swing.JLabel signatureLabel;
private javax.swing.JTextField signatureTextField;
private javax.swing.JComboBox<String> signatureTypeComboBox;
private javax.swing.JLabel signatureTypeLabel;
// End of variables declaration//GEN-END:variables
}

View File

@ -10,17 +10,11 @@ FileTypeIdModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected setting
FileTypeIdModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof FileTypeIdModuleSettings FileTypeIdModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof FileTypeIdModuleSettings
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification. FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification.
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL) FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL)
FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text=0x
FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=Delete FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=Delete
FileTypeIdGlobalSettingsPanel.offsetTextField.text=
FileTypeIdGlobalSettingsPanel.offsetLabel.text=Byte Offset
FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=Alert as an "Interesting File" when found FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=Alert as an "Interesting File" when found
FileTypeIdGlobalSettingsPanel.signatureTextField.text=
FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=Signature Type
FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text= FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text=
FileTypeIdGlobalSettingsPanel.signatureLabel.text=Signature
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME Type FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME Type
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Save FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Add
FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=Bytes (Hex) FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=Bytes (Hex)
FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=String (ASCII) FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=String (ASCII)
FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=Start FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=Start
@ -48,4 +42,13 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=Custom MIME Types:
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here. FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here.
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetLabel.text=Byte Offset
AddFileTypeSignaturePanel.signatureTextField.text=
AddFileTypeSignaturePanel.signatureTypeLabel.text=Signature Type
AddFileTypeSignaturePanel.signatureLabel.text=Signature
AddFileTypeSignaturePanel.hexPrefixLabel.text=0x
AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to
AddFileTypeSignaturePanel.offsetTextField.text=
FileTypeIdGlobalSettingsPanel.deleteSigButton.text=Delete Signature
FileTypeIdGlobalSettingsPanel.addSigButton.text=Add Signature
FileTypeIdGlobalSettingsPanel.editSigButton.text=Edit Signature

View File

@ -24,13 +24,10 @@ FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=\u8aad\u307f\u8fbc\u3
FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title=\u4fdd\u5b58\u304c\u5931\u6557\u3057\u307e\u3057\u305f FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title=\u4fdd\u5b58\u304c\u5931\u6557\u3057\u307e\u3057\u305f
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME\u30bf\u30a4\u30d7 FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.newTypeButton.text=\u65b0\u898f\u30bf\u30a4\u30d7 FileTypeIdGlobalSettingsPanel.newTypeButton.text=\u65b0\u898f\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.offsetLabel.text=\u30d0\u30a4\u30c8\u30aa\u30d5\u30bb\u30c3\u30c8
FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=\u767a\u898b\u3057\u305f\u969b\u306b\u300c\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u300d\u3068\u8b66\u544a FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=\u767a\u898b\u3057\u305f\u969b\u306b\u300c\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u300d\u3068\u8b66\u544a
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=\u4fdd\u5b58\u30bf\u30a4\u30d7 FileTypeIdGlobalSettingsPanel.saveTypeButton.text=\u4fdd\u5b58\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=\u30b9\u30c8\u30ea\u30f3\u30b0\uff08ASCII\uff09 FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=\u30b9\u30c8\u30ea\u30f3\u30b0\uff08ASCII\uff09
FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=\u30d0\u30a4\u30c8\uff08HEX\uff09 FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=\u30d0\u30a4\u30c8\uff08HEX\uff09
FileTypeIdGlobalSettingsPanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3
FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7
OptionsCategory_Keywords_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID OptionsCategory_Keywords_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID
OptionsCategory_Name_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 OptionsCategory_Name_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7
UserDefinedFileTypesManager.loadFileTypes.errorMessage=\u65e2\u5b58\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f UserDefinedFileTypesManager.loadFileTypes.errorMessage=\u65e2\u5b58\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f
@ -43,4 +40,7 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME\u30bf\u30a4\u30d7\uff1a
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306f\u81ea\u52d5\u7684\u306b\u591a\u304f\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u691c\u77e5\u3067\u304d\u307e\u3059\u3002\u3053\u3053\u306b\u306f\u3042\u306a\u305f\u306e\u30ab\u30b9\u30bf\u30e0\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306f\u81ea\u52d5\u7684\u306b\u591a\u304f\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u691c\u77e5\u3067\u304d\u307e\u3059\u3002\u3053\u3053\u306b\u306f\u3042\u306a\u305f\u306e\u30ab\u30b9\u30bf\u30e0\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684 AddFileTypeSignaturePanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7
AddFileTypeSignaturePanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3
AddFileTypeSignaturePanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684
AddFileTypeSignaturePanel.offsetLabel.text=\u30d0\u30a4\u30c8\u30aa\u30d5\u30bb\u30c3\u30c8

View File

@ -19,16 +19,22 @@
package org.sleuthkit.autopsy.modules.filetypeid; package org.sleuthkit.autopsy.modules.filetypeid;
import java.io.Serializable; import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.xml.bind.DatatypeConverter;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Represents a file type characterized by a file signature. * Represents a file type characterized by file signatures.
* <p> * <p>
* Thread-safe (immutable). * Thread-safe (immutable).
*/ */
@ -36,24 +42,24 @@ class FileType implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String mimeType; private final String mimeType;
private final Signature signature; private final List<Signature> signatures;
private final String interestingFilesSetName; private final String interestingFilesSetName;
private final boolean alert; private final boolean alert;
/** /**
* Creates a representation of a file type characterized by a file * Creates a representation of a file type characterized by file
* signature. * signatures.
* *
* @param mimeType The mime type to associate with this file type. * @param mimeType The mime type to associate with this file type.
* @param signature The signature that characterizes this file type. * @param signatures The signatures that characterize this file type.
* @param filesSetName The name of an interesting files set that includes * @param filesSetName The name of an interesting files set that includes
* files of this type, may be the empty string. * files of this type, may be the empty string.
* @param alert Whether the user wishes to be alerted when a file * @param alert Whether the user wishes to be alerted when a file
* matching this type is encountered. * matching this type is encountered.
*/ */
FileType(String mimeType, final Signature signature, String filesSetName, boolean alert) { FileType(String mimeType, List<Signature> signatures, String filesSetName, boolean alert) {
this.mimeType = mimeType; this.mimeType = mimeType;
this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart()); this.signatures = new ArrayList<>(signatures);
this.interestingFilesSetName = filesSetName; this.interestingFilesSetName = filesSetName;
this.alert = alert; this.alert = alert;
} }
@ -68,12 +74,16 @@ class FileType implements Serializable {
} }
/** /**
* Gets the signature associated with this file type. * Gets the signatures associated with this file type.
* *
* @return The signature. * @return The signatures.
*/ */
Signature getSignature() { List<Signature> getSignatures() {
return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart()); return Collections.unmodifiableList(this.signatures);
}
void addSignature(Signature sig) {
this.signatures.add(sig);
} }
/** /**
@ -84,7 +94,12 @@ class FileType implements Serializable {
* @return True or false. * @return True or false.
*/ */
boolean matches(final AbstractFile file) { boolean matches(final AbstractFile file) {
return signature.containedIn(file); for (Signature sig : this.signatures) {
if (!sig.containedIn(file)) {
return false;
}
}
return true;
} }
/** /**
@ -116,7 +131,7 @@ class FileType implements Serializable {
public boolean equals(Object other) { public boolean equals(Object other) {
if (other != null && other instanceof FileType) { if (other != null && other instanceof FileType) {
FileType that = (FileType) other; FileType that = (FileType) other;
if (this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature())) { if (this.getMimeType().equals(that.getMimeType()) && this.getSignatures().equals(that.getSignatures())) {
return true; return true;
} }
} }
@ -127,7 +142,7 @@ class FileType implements Serializable {
public int hashCode() { public int hashCode() {
int hash = 7; int hash = 7;
hash = 67 * hash + Objects.hashCode(this.mimeType); hash = 67 * hash + Objects.hashCode(this.mimeType);
hash = 67 * hash + Objects.hashCode(this.signature); hash = 67 * hash + Objects.hashCode(this.signatures);
return hash; return hash;
} }
@ -138,7 +153,7 @@ class FileType implements Serializable {
* Thread-safe (immutable). * Thread-safe (immutable).
*/ */
static class Signature implements Serializable { static class Signature implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(Signature.class.getName()); private static final Logger logger = Logger.getLogger(Signature.class.getName());
@ -191,8 +206,8 @@ class FileType implements Serializable {
* string, use one of the other constructors so that the string is * string, use one of the other constructors so that the string is
* displayed to the user instead of the raw bytes. * displayed to the user instead of the raw bytes.
* *
* @param signatureBytes The signature bytes. * @param signatureBytes The signatures bytes.
* @param offset The offset of the signature bytes. * @param offset The offset of the signatures bytes.
*/ */
Signature(final byte[] signatureBytes, long offset) { Signature(final byte[] signatureBytes, long offset) {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
@ -339,6 +354,33 @@ class FileType implements Serializable {
hash = 97 * hash + Objects.hashCode(this.type); hash = 97 * hash + Objects.hashCode(this.type);
return hash; return hash;
} }
@Override
public String toString() {
String signatureBytesString;
if (Signature.Type.RAW == this.getType()) {
signatureBytesString = DatatypeConverter.printHexBinary(this.getSignatureBytes());
signatureBytesString = "0x" + signatureBytesString;
} else {
try {
signatureBytesString = new String(this.getSignatureBytes(), "UTF-8");
} catch (UnsupportedEncodingException ex) {
JOptionPane.showMessageDialog(null,
ex.getLocalizedMessage(),
Bundle.AddFileTypeSignaturePanel_signatureStringFail_text(),
JOptionPane.ERROR_MESSAGE);
signatureBytesString = "";
}
}
String startOrEnd;
if (this.isRelativeToStart) {
startOrEnd = "start";
} else {
startOrEnd = "end";
}
return signatureBytesString + ", " + offset + " bytes from " + startOrEnd;
}
} }
} }

View File

@ -3,10 +3,10 @@
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties> <Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[500, 300]"/> <Dimension value="[552, 297]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[500, 300]"/> <Dimension value="[552, 297]"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
@ -33,71 +33,48 @@
</Group> </Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" alignment="0" groupAlignment="1" attributes="0">
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<Component id="deleteTypeButton" min="-2" pref="70" max="-2" attributes="0"/> <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <Group type="102" alignment="0" attributes="0">
<Component id="newTypeButton" min="-2" pref="70" max="-2" attributes="0"/> <EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Component id="deleteTypeButton" min="-2" pref="70" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="newTypeButton" min="-2" pref="70" max="-2" attributes="0"/>
</Group>
<Component id="typesScrollPane" alignment="0" min="-2" pref="180" max="-2" attributes="0"/>
</Group> </Group>
<Component id="typesScrollPane" alignment="0" min="-2" pref="180" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> <Component id="separator" min="-2" pref="7" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="separator" min="-2" pref="7" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Component id="filesSetNameLabel" min="-2" max="-2" attributes="0"/> <Component id="filesSetNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="filesSetNameTextField" min="-2" pref="182" max="-2" attributes="0"/> <Component id="filesSetNameTextField" min="-2" pref="277" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0"> <Component id="jScrollPane1" alignment="0" min="-2" pref="333" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="postHitCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="mimeTypeLabel" min="-2" max="-2" attributes="0"/> <Component id="addSigButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="30" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="mimeTypeTextField" min="-2" pref="176" max="-2" attributes="0"/> <Component id="editSigButton" min="-2" max="-2" attributes="0"/>
</Group> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="postHitCheckBox" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="deleteSigButton" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> </Group>
<Component id="signatureTypeLabel" min="-2" max="-2" attributes="0"/> <Group type="102" alignment="0" attributes="0">
<EmptySpace type="unrelated" max="-2" attributes="0"/> <Component id="mimeTypeLabel" min="-2" max="-2" attributes="0"/>
<Component id="signatureTypeComboBox" min="-2" pref="176" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
</Group> <Component id="mimeTypeTextField" min="-2" pref="262" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="signatureLabel" min="-2" pref="73" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="hexPrefixLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="signatureTextField" min="-2" pref="160" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="offsetLabel" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="offsetTextField" min="-2" pref="178" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
</Group> </Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="offsetRelativeToLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="offsetRelativeToComboBox" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace pref="28" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -115,7 +92,7 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="typesScrollPane" max="32767" attributes="0"/> <Component id="typesScrollPane" pref="183" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="deleteTypeButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="deleteTypeButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
@ -134,29 +111,14 @@
<Component id="mimeTypeTextField" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="mimeTypeTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="jScrollPane1" min="-2" pref="83" max="-2" attributes="0"/>
<Component id="signatureTypeComboBox" min="-2" max="-2" attributes="0"/>
<Component id="signatureTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
<Component id="hexPrefixLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="signatureTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="signatureLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="offsetLabel" min="-2" max="-2" attributes="0"/> <Component id="addSigButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="offsetTextField" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="editSigButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteSigButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="offsetRelativeToComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="offsetRelativeToLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Component id="postHitCheckBox" min="-2" max="-2" attributes="0"/> <Component id="postHitCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
@ -165,7 +127,6 @@
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="saveTypeButton" linkSize="2" min="-2" max="-2" attributes="0"/> <Component id="saveTypeButton" linkSize="2" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="21" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -232,57 +193,6 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="signatureTypeLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTypeLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="signatureTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTextField" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.signatureTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="signatureTextFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="offsetLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.offsetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="offsetTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetTextField" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.offsetTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="newTypeButton"> <Component class="javax.swing.JButton" name="newTypeButton">
<Properties> <Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor"> <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
@ -328,48 +238,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveTypeButtonActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveTypeButtonActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JLabel" name="hexPrefixLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="hexPrefixLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="signatureTypeComboBox">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureTypeComboBox" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="signatureTypeComboBoxActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="signatureLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="signatureLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.signatureLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="postHitCheckBox"> <Component class="javax.swing.JCheckBox" name="postHitCheckBox">
<Properties> <Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor"> <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
@ -448,32 +316,54 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JComboBox" name="offsetRelativeToComboBox"> <Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetRelativeToComboBox" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
<AuxValues> <AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/> <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues> </AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="offsetRelativeToLabel"> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="signatureList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.AbstractListModel&lt;Signature&gt;() {&#xa; Signature[] signatures = {};&#xa; public int getSize() { return signatures.length; }&#xa; public Signature getElementAt(int i) { return signatures[i]; }&#xa;}" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;Signature&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="addSigButton">
<Properties> <Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="offsetRelativeToLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.addSigButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addSigButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="editSigButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.editSigButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="editSigButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deleteSigButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.deleteSigButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteSigButtonActionPerformed"/>
</Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -21,9 +21,9 @@ package org.sleuthkit.autopsy.modules.filetypeid;
import java.awt.*; import java.awt.*;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.UnsupportedEncodingException; import java.util.ArrayList;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
@ -31,11 +31,12 @@ import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.xml.bind.DatatypeConverter;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.modules.filetypeid.AddFileTypeSignatureDialog.BUTTON_PRESSED;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
import org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException; import org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException;
@ -59,6 +60,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
*/ */
private DefaultListModel<FileType> typesListModel; private DefaultListModel<FileType> typesListModel;
private java.util.List<FileType> fileTypes; private java.util.List<FileType> fileTypes;
private AddFileTypeSignatureDialog addSigDialog;
private DefaultListModel<Signature> signaturesListModel;
/** /**
* This panel implements a property change listener that listens to ingest * This panel implements a property change listener that listens to ingest
@ -86,8 +89,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
*/ */
@NbBundle.Messages({"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"}) @NbBundle.Messages({"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"})
private void customizeComponents() { private void customizeComponents() {
setName(Bundle.FileTypeIdGlobalSettingsPanel_Title()); setName(Bundle.FileTypeIdGlobalSettingsPanel_Title());
setFileTypesListModel(); setFileTypesListModel();
setSignaturesListModel();
setSignatureTypeComboBoxModel(); setSignatureTypeComboBoxModel();
setOffsetRealtiveToComboBoxModel(); setOffsetRealtiveToComboBoxModel();
clearTypeDetailsComponents(); clearTypeDetailsComponents();
@ -103,6 +107,11 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
typesList.setModel(typesListModel); typesList.setModel(typesListModel);
} }
private void setSignaturesListModel() {
this.signaturesListModel = new DefaultListModel<>();
signatureList.setModel(signaturesListModel);
}
/** /**
* Sets the model for the signature type combo box. * Sets the model for the signature type combo box.
*/ */
@ -110,10 +119,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
DefaultComboBoxModel<String> sigTypeComboBoxModel = new DefaultComboBoxModel<>(); DefaultComboBoxModel<String> sigTypeComboBoxModel = new DefaultComboBoxModel<>();
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
signatureTypeComboBox.setModel(sigTypeComboBoxModel);
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
} }
/** /**
* Sets the model for the signature type combo box. * Sets the model for the signature type combo box.
*/ */
@ -121,8 +128,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
DefaultComboBoxModel<String> offsetRelComboBoxModel = new DefaultComboBoxModel<>(); DefaultComboBoxModel<String> offsetRelComboBoxModel = new DefaultComboBoxModel<>();
offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM); offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM); offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetRelativeToComboBox.setModel(offsetRelComboBoxModel);
offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
} }
/** /**
@ -168,8 +173,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
}; };
mimeTypeTextField.getDocument().addDocumentListener(listener); mimeTypeTextField.getDocument().addDocumentListener(listener);
offsetTextField.getDocument().addDocumentListener(listener);
signatureTextField.getDocument().addDocumentListener(listener);
filesSetNameTextField.getDocument().addDocumentListener(listener); filesSetNameTextField.getDocument().addDocumentListener(listener);
} }
@ -216,8 +219,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
boolean requiredFieldsPopulated boolean requiredFieldsPopulated
= !mimeTypeTextField.getText().isEmpty() = !mimeTypeTextField.getText().isEmpty()
&& !offsetTextField.getText().isEmpty()
&& !signatureTextField.getText().isEmpty()
&& (postHitCheckBox.isSelected() ? !filesSetNameTextField.getText().isEmpty() : true); && (postHitCheckBox.isSelected() ? !filesSetNameTextField.getText().isEmpty() : true);
saveTypeButton.setEnabled(!ingestIsRunning && requiredFieldsPopulated); saveTypeButton.setEnabled(!ingestIsRunning && requiredFieldsPopulated);
@ -265,29 +266,18 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
if (null != fileType) { if (null != fileType) {
mimeTypeTextField.setText(fileType.getMimeType()); mimeTypeTextField.setText(fileType.getMimeType());
mimeTypeTextField.setEditable(false); mimeTypeTextField.setEditable(false);
Signature signature = fileType.getSignature(); List<Signature> signatures = fileType.getSignatures();
FileType.Signature.Type sigType = signature.getType(); this.signaturesListModel.clear();
signatureTypeComboBox.setSelectedItem(sigType == FileType.Signature.Type.RAW ? FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); for (Signature sig : signatures) {
String signatureBytes; signaturesListModel.addElement(sig);
if (Signature.Type.RAW == signature.getType()) {
signatureBytes = DatatypeConverter.printHexBinary(signature.getSignatureBytes());
} else {
try {
signatureBytes = new String(signature.getSignatureBytes(), "UTF-8");
} catch (UnsupportedEncodingException ex) {
JOptionPane.showMessageDialog(null,
ex.getLocalizedMessage(),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"),
JOptionPane.ERROR_MESSAGE);
signatureBytes = "";
}
} }
signatureTextField.setText(signatureBytes);
offsetRelativeToComboBox.setSelectedItem(signature.isRelativeToStart() ? FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetTextField.setText(Long.toString(signature.getOffset()));
postHitCheckBox.setSelected(fileType.alertOnMatch()); postHitCheckBox.setSelected(fileType.alertOnMatch());
filesSetNameTextField.setEnabled(postHitCheckBox.isSelected()); filesSetNameTextField.setEnabled(postHitCheckBox.isSelected());
filesSetNameTextField.setText(fileType.getFilesSetName()); filesSetNameTextField.setText(fileType.getFilesSetName());
this.signatureList.setEnabled(false);
this.addSigButton.setEnabled(false);
this.deleteSigButton.setEnabled(false);
this.editSigButton.setEnabled(false);
} }
enableButtons(); enableButtons();
} }
@ -300,14 +290,14 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
typesList.clearSelection(); typesList.clearSelection();
mimeTypeTextField.setText(""); //NON-NLS mimeTypeTextField.setText(""); //NON-NLS
mimeTypeTextField.setEditable(true); mimeTypeTextField.setEditable(true);
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); this.signatureList.setEnabled(true);
hexPrefixLabel.setVisible(true); this.addSigButton.setEnabled(true);
signatureTextField.setText("0000"); //NON-NLS this.deleteSigButton.setEnabled(true);
offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM); this.editSigButton.setEnabled(true);
offsetTextField.setText(""); //NON-NLS
postHitCheckBox.setSelected(false); postHitCheckBox.setSelected(false);
filesSetNameTextField.setText(""); //NON-NLS filesSetNameTextField.setText(""); //NON-NLS
filesSetNameTextField.setEnabled(false); filesSetNameTextField.setEnabled(false);
this.signaturesListModel.clear();
enableButtons(); enableButtons();
} }
@ -354,31 +344,27 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private void initComponents() { private void initComponents() {
typesScrollPane = new javax.swing.JScrollPane(); typesScrollPane = new javax.swing.JScrollPane();
typesList = new javax.swing.JList<FileType>(); typesList = new javax.swing.JList<>();
separator = new javax.swing.JSeparator(); separator = new javax.swing.JSeparator();
mimeTypeLabel = new javax.swing.JLabel(); mimeTypeLabel = new javax.swing.JLabel();
mimeTypeTextField = new javax.swing.JTextField(); mimeTypeTextField = new javax.swing.JTextField();
signatureTypeLabel = new javax.swing.JLabel();
signatureTextField = new javax.swing.JTextField();
offsetLabel = new javax.swing.JLabel();
offsetTextField = new javax.swing.JTextField();
newTypeButton = new javax.swing.JButton(); newTypeButton = new javax.swing.JButton();
deleteTypeButton = new javax.swing.JButton(); deleteTypeButton = new javax.swing.JButton();
saveTypeButton = new javax.swing.JButton(); saveTypeButton = new javax.swing.JButton();
hexPrefixLabel = new javax.swing.JLabel();
signatureTypeComboBox = new javax.swing.JComboBox<String>();
signatureLabel = new javax.swing.JLabel();
postHitCheckBox = new javax.swing.JCheckBox(); postHitCheckBox = new javax.swing.JCheckBox();
filesSetNameLabel = new javax.swing.JLabel(); filesSetNameLabel = new javax.swing.JLabel();
filesSetNameTextField = new javax.swing.JTextField(); filesSetNameTextField = new javax.swing.JTextField();
ingestRunningWarningLabel = new javax.swing.JLabel(); ingestRunningWarningLabel = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel();
offsetRelativeToComboBox = new javax.swing.JComboBox<String>(); jScrollPane1 = new javax.swing.JScrollPane();
offsetRelativeToLabel = new javax.swing.JLabel(); signatureList = new javax.swing.JList<>();
addSigButton = new javax.swing.JButton();
editSigButton = new javax.swing.JButton();
deleteSigButton = new javax.swing.JButton();
setMaximumSize(new java.awt.Dimension(500, 300)); setMaximumSize(new java.awt.Dimension(552, 297));
setPreferredSize(new java.awt.Dimension(500, 300)); setPreferredSize(new java.awt.Dimension(552, 297));
typesList.setFont(typesList.getFont().deriveFont(typesList.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); typesList.setFont(typesList.getFont().deriveFont(typesList.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
typesList.setMaximumSize(new java.awt.Dimension(150, 0)); typesList.setMaximumSize(new java.awt.Dimension(150, 0));
@ -393,23 +379,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
mimeTypeTextField.setFont(mimeTypeTextField.getFont().deriveFont(mimeTypeTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); mimeTypeTextField.setFont(mimeTypeTextField.getFont().deriveFont(mimeTypeTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
mimeTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text")); // NOI18N mimeTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text")); // NOI18N
signatureTypeLabel.setFont(signatureTypeLabel.getFont().deriveFont(signatureTypeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(signatureTypeLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text")); // NOI18N
signatureTextField.setFont(signatureTextField.getFont().deriveFont(signatureTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
signatureTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureTextField.text")); // NOI18N
signatureTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
signatureTextFieldActionPerformed(evt);
}
});
offsetLabel.setFont(offsetLabel.getFont().deriveFont(offsetLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(offsetLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetLabel.text")); // NOI18N
offsetTextField.setFont(offsetTextField.getFont().deriveFont(offsetTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
offsetTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetTextField.text")); // NOI18N
newTypeButton.setFont(newTypeButton.getFont().deriveFont(newTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); newTypeButton.setFont(newTypeButton.getFont().deriveFont(newTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N
newTypeButton.addActionListener(new java.awt.event.ActionListener() { newTypeButton.addActionListener(new java.awt.event.ActionListener() {
@ -434,19 +403,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
} }
}); });
hexPrefixLabel.setFont(hexPrefixLabel.getFont().deriveFont(hexPrefixLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text")); // NOI18N
signatureTypeComboBox.setFont(signatureTypeComboBox.getFont().deriveFont(signatureTypeComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
signatureTypeComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
signatureTypeComboBoxActionPerformed(evt);
}
});
signatureLabel.setFont(signatureLabel.getFont().deriveFont(signatureLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureLabel.text")); // NOI18N
postHitCheckBox.setFont(postHitCheckBox.getFont().deriveFont(postHitCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); postHitCheckBox.setFont(postHitCheckBox.getFont().deriveFont(postHitCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(postHitCheckBox, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.postHitCheckBox.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(postHitCheckBox, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.postHitCheckBox.text")); // NOI18N
postHitCheckBox.addActionListener(new java.awt.event.ActionListener() { postHitCheckBox.addActionListener(new java.awt.event.ActionListener() {
@ -471,10 +427,33 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N
offsetRelativeToComboBox.setFont(offsetRelativeToComboBox.getFont().deriveFont(offsetRelativeToComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); signatureList.setModel(new javax.swing.AbstractListModel<Signature>() {
Signature[] signatures = {};
public int getSize() { return signatures.length; }
public Signature getElementAt(int i) { return signatures[i]; }
});
jScrollPane1.setViewportView(signatureList);
offsetRelativeToLabel.setFont(offsetRelativeToLabel.getFont().deriveFont(offsetRelativeToLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(addSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.addSigButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(offsetRelativeToLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text")); // NOI18N addSigButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addSigButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(editSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.editSigButton.text")); // NOI18N
editSigButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
editSigButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(deleteSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteSigButton.text")); // NOI18N
deleteSigButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deleteSigButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -488,56 +467,39 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGap(30, 30, 30)) .addGap(30, 30, 30))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addComponent(jLabel3)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel2) .addComponent(saveTypeButton)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(deleteTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(newTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(typesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jLabel2)
.addGap(21, 21, 21) .addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(deleteTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(newTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(typesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(filesSetNameLabel) .addComponent(filesSetNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(postHitCheckBox)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(addSigButton)
.addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(mimeTypeLabel) .addComponent(editSigButton)
.addGap(30, 30, 30) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(deleteSigButton))
.addComponent(postHitCheckBox) .addGroup(layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup() .addComponent(mimeTypeLabel)
.addComponent(signatureTypeLabel) .addGap(18, 18, 18)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE))))))
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addGroup(layout.createSequentialGroup()
.addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(hexPrefixLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(6, 6, 6)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(saveTypeButton)
.addGap(8, 8, 8))
.addGroup(layout.createSequentialGroup()
.addComponent(offsetRelativeToLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addComponent(jLabel3))
.addContainerGap(28, Short.MAX_VALUE))))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -551,7 +513,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jLabel2) .addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(typesScrollPane) .addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(deleteTypeButton) .addComponent(deleteTypeButton)
@ -565,32 +527,20 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(mimeTypeLabel) .addComponent(mimeTypeLabel)
.addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(signatureTypeLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(hexPrefixLabel)
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(signatureLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(offsetLabel)
.addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(addSigButton)
.addComponent(offsetRelativeToLabel)) .addComponent(editSigButton)
.addGap(16, 16, 16) .addComponent(deleteSigButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(postHitCheckBox) .addComponent(postHitCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(filesSetNameLabel) .addComponent(filesSetNameLabel)
.addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(saveTypeButton) .addComponent(saveTypeButton))))
.addGap(0, 21, Short.MAX_VALUE))))
); );
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton}); layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton});
@ -609,11 +559,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
typesList.setSelectedIndex(0); typesList.setSelectedIndex(0);
} }
}//GEN-LAST:event_deleteTypeButtonActionPerformed }//GEN-LAST:event_deleteTypeButtonActionPerformed
@Messages({
"FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSigList.message=Must have at least one signature.",
"FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSigList.title=Invalid Signature List"})
private void saveTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTypeButtonActionPerformed private void saveTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTypeButtonActionPerformed
/**
* Get the MIME type.
*/
String typeName = mimeTypeTextField.getText(); String typeName = mimeTypeTextField.getText();
if (typeName.isEmpty()) { if (typeName.isEmpty()) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
@ -622,61 +571,17 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
return; return;
} }
List<Signature> sigList = new ArrayList<>();
/** for (int i = 0; i < this.signaturesListModel.getSize(); i++) {
* Get the signature type. sigList.add(this.signaturesListModel.elementAt(i));
*/ }
FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII; if (sigList.isEmpty()) {
/**
* Get the signature bytes.
*/
String sigString = signatureTextField.getText();
if (sigString.isEmpty()) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message"), Bundle.AddFileTypeSignatureDialog_invalidSignature_message(),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title"), Bundle.FileTypeIdGlobalSettingsPanel_JOptionPane_invalidSigList_title(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
return; return;
} }
byte[] signatureBytes;
if (FileType.Signature.Type.RAW == sigType) {
try {
sigString = sigString.replaceAll("\\s", ""); //NON-NLS
signatureBytes = DatatypeConverter.parseHexBinary(sigString);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"),
JOptionPane.ERROR_MESSAGE);
return;
}
} else {
signatureBytes = sigString.getBytes(Charset.forName("UTF-8"));
}
/**
* Get the offset.
*/
long offset;
boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM;
try {
offset = Long.parseUnsignedLong(offsetTextField.getText());
if(!isRelativeToStart && signatureBytes.length > offset+1) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"),
JOptionPane.ERROR_MESSAGE);
return;
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"),
JOptionPane.ERROR_MESSAGE);
return;
}
/** /**
* Get the interesting files set details. * Get the interesting files set details.
*/ */
@ -691,12 +596,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
return; return;
} }
FileType fileType = new FileType(typeName, sigList, filesSetName, postHitCheckBox.isSelected());
/**
* Put it all together and reset the file types list component.
*/
FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart);
FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected());
FileType selected = typesList.getSelectedValue(); FileType selected = typesList.getSelectedValue();
if (selected != null) { if (selected != null) {
fileTypes.remove(selected); fileTypes.remove(selected);
@ -711,42 +611,52 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
enableButtons(); enableButtons();
}//GEN-LAST:event_postHitCheckBoxActionPerformed }//GEN-LAST:event_postHitCheckBoxActionPerformed
private void signatureTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTypeComboBoxActionPerformed private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed
if (signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM) { if (evt.getSource().equals(this.addSigButton)) {
hexPrefixLabel.setVisible(true); this.addSigDialog = new AddFileTypeSignatureDialog();
signatureTextField.setText("0000"); if (addSigDialog.getResult() == BUTTON_PRESSED.OK) {
} else { signaturesListModel.addElement(this.addSigDialog.getSignature());
hexPrefixLabel.setVisible(false); }
signatureTextField.setText("");
} }
}//GEN-LAST:event_signatureTypeComboBoxActionPerformed }//GEN-LAST:event_addSigButtonActionPerformed
private void signatureTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTextFieldActionPerformed private void deleteSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSigButtonActionPerformed
// TODO add your handling code here: if (this.signatureList.getSelectedIndex() != -1) {
}//GEN-LAST:event_signatureTextFieldActionPerformed signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex());
if (!this.signaturesListModel.isEmpty()) {
signatureList.setSelectedIndex(0);
}
}
}//GEN-LAST:event_deleteSigButtonActionPerformed
private void editSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSigButtonActionPerformed
if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) {
this.addSigDialog = new AddFileTypeSignatureDialog(this.signatureList.getSelectedValue());
if (addSigDialog.getResult() == BUTTON_PRESSED.OK) {
signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex());
this.signaturesListModel.addElement(this.addSigDialog.getSignature());
}
}
}//GEN-LAST:event_editSigButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addSigButton;
private javax.swing.JButton deleteSigButton;
private javax.swing.JButton deleteTypeButton; private javax.swing.JButton deleteTypeButton;
private javax.swing.JButton editSigButton;
private javax.swing.JLabel filesSetNameLabel; private javax.swing.JLabel filesSetNameLabel;
private javax.swing.JTextField filesSetNameTextField; private javax.swing.JTextField filesSetNameTextField;
private javax.swing.JLabel hexPrefixLabel;
private javax.swing.JLabel ingestRunningWarningLabel; private javax.swing.JLabel ingestRunningWarningLabel;
private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel mimeTypeLabel; private javax.swing.JLabel mimeTypeLabel;
private javax.swing.JTextField mimeTypeTextField; private javax.swing.JTextField mimeTypeTextField;
private javax.swing.JButton newTypeButton; private javax.swing.JButton newTypeButton;
private javax.swing.JLabel offsetLabel;
private javax.swing.JComboBox<String> offsetRelativeToComboBox;
private javax.swing.JLabel offsetRelativeToLabel;
private javax.swing.JTextField offsetTextField;
private javax.swing.JCheckBox postHitCheckBox; private javax.swing.JCheckBox postHitCheckBox;
private javax.swing.JButton saveTypeButton; private javax.swing.JButton saveTypeButton;
private javax.swing.JSeparator separator; private javax.swing.JSeparator separator;
private javax.swing.JLabel signatureLabel; private javax.swing.JList<Signature> signatureList;
private javax.swing.JTextField signatureTextField;
private javax.swing.JComboBox<String> signatureTypeComboBox;
private javax.swing.JLabel signatureTypeLabel;
private javax.swing.JList<FileType> typesList; private javax.swing.JList<FileType> typesList;
private javax.swing.JScrollPane typesScrollPane; private javax.swing.JScrollPane typesScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

View File

@ -29,12 +29,8 @@ import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.persistence.PersistenceException;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream; import org.openide.util.io.NbObjectInputStream;
@ -43,8 +39,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
import org.sleuthkit.datamodel.TskCoreException; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
/** /**
@ -188,56 +186,123 @@ final class UserDefinedFileTypesManager {
FileType fileType; FileType fileType;
try { try {
// Add rule for xml List<Signature> signatureList;
fileType = new FileType("text/xml", new Signature("<?xml", 0L), "", false); //NON-NLS signatureList = new ArrayList<>();
signatureList.add(new Signature("<?xml", 0L));
fileType = new FileType("text/xml", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for gzip // Add rule for gzip
byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS
fileType = new FileType("application/x-gzip", new Signature(byteArray, 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 0L));
fileType = new FileType("application/x-gzip", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .wk1 // Add rule for .wk1
byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS
fileType = new FileType("application/x-123", new Signature(byteArray, 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 0L));
fileType = new FileType("application/x-123", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for Radiance image // Add rule for Radiance image
byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS
fileType = new FileType("image/vnd.radiance", new Signature(byteArray, 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 0L));
fileType = new FileType("image/vnd.radiance", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .dcx image // Add rule for .dcx image
byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS
fileType = new FileType("image/x-dcx", new Signature(byteArray, 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 0L));
fileType = new FileType("image/x-dcx", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .ics image // Add rule for .ics image
fileType = new FileType("image/x-icns", new Signature("icns", 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature("icns", 0L));
fileType = new FileType("image/x-icns", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .pict image // Add rule for .pict image
byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS
fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 522L));
fileType = new FileType("image/x-pict", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
byteArray = DatatypeConverter.parseHexBinary("1100"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("1100"); //NON-NLS
fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 522L));
fileType = new FileType("image/x-pict", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .pam // Add rule for .pam
fileType = new FileType("image/x-portable-arbitrarymap", new Signature("P7", 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature("P7", 0L));
fileType = new FileType("image/x-portable-arbitrarymap", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .pfm // Add rule for .pfm
fileType = new FileType("image/x-portable-floatmap", new Signature("PF", 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature("PF", 0L));
fileType = new FileType("image/x-portable-floatmap", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
fileType = new FileType("image/x-portable-floatmap", new Signature("Pf", 0L), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature("Pf", 0L));
fileType = new FileType("image/x-portable-floatmap", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .tga // Add rule for .tga
byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS signatureList.clear();
signatureList.add(new Signature(byteArray, 17, false));
fileType = new FileType("image/x-tga", signatureList, "", false); //NON-NLS
fileTypes.add(fileType); fileTypes.add(fileType);
// Add rule for .ilbm
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
signatureList.add(new Signature("ILBM", 8L));
fileType = new FileType("image/x-ilbm", signatureList, "", false);
fileTypes.add(fileType);
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
signatureList.add(new Signature("PBM", 8L));
fileType = new FileType("image/x-ilbm", signatureList, "", false);
fileTypes.add(fileType);
// Add rule for .webp
signatureList.clear();
signatureList.add(new Signature("RIFF", 0L));
signatureList.add(new Signature("WEBP", 8L));
fileType = new FileType("image/webp", signatureList, "", false);
fileTypes.add(fileType);
// Add rule for .aiff
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
signatureList.add(new Signature("AIFF", 8L));
fileType = new FileType("audio/aiff", signatureList, "", false);
fileTypes.add(fileType);
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
signatureList.add(new Signature("AIFC", 8L));
fileType = new FileType("audio/aiff", signatureList, "", false);
fileTypes.add(fileType);
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
signatureList.add(new Signature("8SVX", 8L));
fileType = new FileType("audio/aiff", signatureList, "", false);
fileTypes.add(fileType);
// Add .iff
signatureList.clear();
signatureList.add(new Signature("FORM", 0L));
fileType = new FileType("application/x-iff", signatureList, "", false);
fileTypes.add(fileType);
} // parseHexBinary() throws this if the argument passed in is not Hex } // parseHexBinary() throws this if the argument passed in is not Hex
catch (IllegalArgumentException e) { catch (IllegalArgumentException e) {
throw new UserDefinedFileTypesException("Error creating predefined file types", e); // throw new UserDefinedFileTypesException("Error creating predefined file types", e); //
@ -409,7 +474,11 @@ final class UserDefinedFileTypesManager {
Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem); Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem);
String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem); String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem);
boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem); boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem);
return new FileType(mimeType, signature, filesSetName, alert); // File type definitions in the XML file were written prior to the
// implementation of multiple signatures per type.
List<Signature> sigList = new ArrayList<>();
sigList.add(signature);
return new FileType(mimeType, sigList, filesSetName, alert);
} }
/** /**

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2014 Basis Technology Corp. * Copyright 2011 - 2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,43 +19,36 @@
package org.sleuthkit.autopsy.modules.hashdatabase; package org.sleuthkit.autopsy.modules.hashdatabase;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.FileUtils;
import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupSettings.HashDbInfo;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.HashHitInfo;
import org.sleuthkit.datamodel.HashEntry; import org.sleuthkit.datamodel.HashEntry;
import org.sleuthkit.datamodel.HashHitInfo;
import org.sleuthkit.datamodel.SleuthkitJNI; import org.sleuthkit.datamodel.SleuthkitJNI;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestManager;
/** /**
* This class implements a singleton that manages the set of hash databases used * This class implements a singleton that manages the set of hash databases used
@ -63,20 +56,8 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
*/ */
public class HashDbManager implements PropertyChangeListener { public class HashDbManager implements PropertyChangeListener {
private static final String ROOT_ELEMENT = "hash_sets"; //NON-NLS
private static final String SET_ELEMENT = "hash_set"; //NON-NLS
private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS
private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS
private static final String SEARCH_DURING_INGEST_ATTRIBUTE = "use_for_ingest"; //NON-NLS
private static final String SEND_INGEST_MESSAGES_ATTRIBUTE = "show_inbox_messages"; //NON-NLS
private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS
private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS
private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS
private static final String XSD_FILE_NAME = "HashsetsSchema.xsd"; //NON-NLS
private static final String ENCODING = "UTF-8"; //NON-NLS
private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS
private static HashDbManager instance = null; private static HashDbManager instance = null;
private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
private List<HashDb> knownHashSets = new ArrayList<>(); private List<HashDb> knownHashSets = new ArrayList<>();
private List<HashDb> knownBadHashSets = new ArrayList<>(); private List<HashDb> knownBadHashSets = new ArrayList<>();
private Set<String> hashSetNames = new HashSet<>(); private Set<String> hashSetNames = new HashSet<>();
@ -108,10 +89,12 @@ public class HashDbManager implements PropertyChangeListener {
changeSupport.addPropertyChangeListener(listener); changeSupport.addPropertyChangeListener(listener);
} }
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
private HashDbManager() { private HashDbManager() {
if (hashSetsConfigurationFileExists()) { loadHashsetsConfiguration();
readHashSetsConfigurationFromDisk();
}
} }
/** /**
@ -125,9 +108,15 @@ public class HashDbManager implements PropertyChangeListener {
public class HashDbManagerException extends Exception { public class HashDbManagerException extends Exception {
private static final long serialVersionUID = 1L;
private HashDbManagerException(String message) { private HashDbManagerException(String message) {
super(message); super(message);
} }
private HashDbManagerException(String message, Throwable exception) {
super(message, exception);
}
} }
/** /**
@ -477,7 +466,11 @@ public class HashDbManager implements PropertyChangeListener {
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
synchronized boolean save() { synchronized boolean save() {
return writeHashSetConfigurationToDisk(); try {
return HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets));
} catch (HashLookupSettings.HashLookupSettingsException ex) {
return false;
}
} }
/** /**
@ -490,9 +483,7 @@ public class HashDbManager implements PropertyChangeListener {
hashSetNames.clear(); hashSetNames.clear();
hashSetPaths.clear(); hashSetPaths.clear();
if (hashSetsConfigurationFileExists()) { loadHashsetsConfiguration();
readHashSetsConfigurationFromDisk();
}
} }
private void closeHashDatabases(List<HashDb> hashDatabases) { private void closeHashDatabases(List<HashDb> hashDatabases) {
@ -506,198 +497,51 @@ public class HashDbManager implements PropertyChangeListener {
hashDatabases.clear(); hashDatabases.clear();
} }
private boolean writeHashSetConfigurationToDisk() { private void loadHashsetsConfiguration() {
boolean success = false;
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
try { try {
DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); HashLookupSettings settings = HashLookupSettings.readSettings();
Document doc = docBuilder.newDocument(); this.configureSettings(settings);
Element rootEl = doc.createElement(ROOT_ELEMENT); } catch (HashLookupSettings.HashLookupSettingsException ex) {
doc.appendChild(rootEl); Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read Hash lookup settings from disk.", ex);
writeHashDbsToDisk(doc, rootEl, knownHashSets);
writeHashDbsToDisk(doc, rootEl, knownBadHashSets);
success = XMLUtil.saveDoc(HashDbManager.class, configFilePath, ENCODING, doc);
} catch (ParserConfigurationException ex) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error saving hash databases", ex); //NON-NLS
} }
return success;
} }
private static void writeHashDbsToDisk(Document doc, Element rootEl, List<HashDb> hashDbs) { /**
for (HashDb db : hashDbs) { * Configures the given settings object by adding all contained hash db to
// Get the path for the hash database before writing anything, in * the system.
// case an exception is thrown. *
String path; * @param settings The settings to configure.
*/
@Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}"})
private void configureSettings(HashLookupSettings settings) {
boolean dbInfoRemoved = false;
List<HashDbInfo> hashDbInfoList = settings.getHashDbInfo();
for (HashDbInfo hashDb : hashDbInfoList) {
try { try {
if (db.hasIndexOnly()) { String dbPath = this.getValidFilePath(hashDb.getHashSetName(), hashDb.getPath());
path = db.getIndexPath(); if (dbPath != null) {
addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType());
} else { } else {
path = db.getDatabasePath(); logger.log(Level.WARNING, Bundle.HashDbManager_noDbPath_message(hashDb.getHashSetName()));
dbInfoRemoved = true;
} }
} catch (TskCoreException ex) { } catch (HashDbManagerException | TskCoreException ex) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting path of hash database " + db.getHashSetName() + ", discarding from hash database configuration", ex); //NON-NLS Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS
continue;
}
Element setElement = doc.createElement(SET_ELEMENT);
setElement.setAttribute(SET_NAME_ATTRIBUTE, db.getHashSetName());
setElement.setAttribute(SET_TYPE_ATTRIBUTE, db.getKnownFilesType().toString());
setElement.setAttribute(SEARCH_DURING_INGEST_ATTRIBUTE, Boolean.toString(db.getSearchDuringIngest()));
setElement.setAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE, Boolean.toString(db.getSendIngestMessages()));
Element pathElement = doc.createElement(PATH_ELEMENT);
pathElement.setTextContent(path);
setElement.appendChild(pathElement);
rootEl.appendChild(setElement);
}
}
private boolean hashSetsConfigurationFileExists() {
File f = new File(configFilePath);
return f.exists() && f.canRead() && f.canWrite();
}
private boolean readHashSetsConfigurationFromDisk() {
boolean updatedSchema = false;
// Open the XML document that implements the configuration file.
final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath);
if (doc == null) {
return false;
}
// Get the root element.
Element root = doc.getDocumentElement();
if (root == null) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS
return false;
}
// Get the hash set elements.
NodeList setsNList = root.getElementsByTagName(SET_ELEMENT);
int numSets = setsNList.getLength();
if (numSets == 0) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS
}
// Create HashDb objects for each hash set element. Skip to the next hash database if the definition of
// a particular hash database is not well-formed.
String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS
String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS
for (int i = 0; i < numSets; ++i) {
Element setEl = (Element) setsNList.item(i);
String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE);
if (hashSetName.isEmpty()) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i);
continue;
}
// Handle configurations saved before duplicate hash set names were not permitted.
if (hashSetNames.contains(hashSetName)) {
int suffix = 0;
String newHashSetName;
do {
++suffix;
newHashSetName = hashSetName + suffix;
} while (hashSetNames.contains(newHashSetName));
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbManager.replacingDuplicateHashsetNameMsg", "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()),
hashSetName, newHashSetName),
NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
hashSetName = newHashSetName; dbInfoRemoved = true;
}
String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE);
if (knownFilesType.isEmpty()) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i);
continue;
}
// Handle legacy known files types.
if (knownFilesType.equals("NSRL")) { //NON-NLS
knownFilesType = HashDb.KnownFilesType.KNOWN.toString();
updatedSchema = true;
}
final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE);
if (searchDuringIngest.isEmpty()) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i);
continue;
}
Boolean seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest);
final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE);
if (searchDuringIngest.isEmpty()) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i);
continue;
}
Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages);
String dbPath;
NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT);
if (pathsNList.getLength() > 0) {
Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one.
// Check for legacy path number attribute.
String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE);
if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) {
updatedSchema = true;
}
dbPath = pathEl.getTextContent();
if (dbPath.isEmpty()) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
continue;
}
} else {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
continue;
}
dbPath = getValidFilePath(hashSetName, dbPath);
if (null != dbPath) {
try {
addExistingHashDatabaseInternal(hashSetName, dbPath, seearchDuringIngestFlag, sendIngestMessagesFlag, HashDb.KnownFilesType.valueOf(knownFilesType));
} catch (HashDbManagerException | TskCoreException ex) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"HashDbManager.unableToOpenHashDbMsg", dbPath),
NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"),
JOptionPane.ERROR_MESSAGE);
}
} else {
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS
} }
} }
if (dbInfoRemoved) {
if (updatedSchema) {
String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS
String messageBoxTitle = NbBundle.getMessage(this.getClass(),
"HashDbManager.msgBoxTitle.confFileFmtChanged");
String baseMessage = NbBundle.getMessage(this.getClass(),
"HashDbManager.baseMessage.updatedFormatHashDbConfig");
try { try {
FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets));
JOptionPane.showMessageDialog(null, } catch (HashLookupSettings.HashLookupSettingsException ex) {
NbBundle.getMessage(this.getClass(), logger.log(Level.SEVERE, "Could not overwrite hash database settings.", ex);
"HashDbManager.savedBackupOfOldConfigMsg",
baseMessage, backupFilePath),
messageBoxTitle,
JOptionPane.INFORMATION_MESSAGE);
} catch (IOException ex) {
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS
JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE);
} }
writeHashSetConfigurationToDisk();
} }
return true;
} }
private String getValidFilePath(String hashSetName, String configuredPath) { private String getValidFilePath(String hashSetName, String configuredPath) {
@ -760,7 +604,7 @@ public class HashDbManager implements PropertyChangeListener {
KNOWN(NbBundle.getMessage(HashDbManager.class, "HashDbManager.known.text")), KNOWN(NbBundle.getMessage(HashDbManager.class, "HashDbManager.known.text")),
KNOWN_BAD(NbBundle.getMessage(HashDbManager.class, "HashDbManager.knownBad.text")); KNOWN_BAD(NbBundle.getMessage(HashDbManager.class, "HashDbManager.knownBad.text"));
private String displayName; private final String displayName;
private KnownFilesType(String displayName) { private KnownFilesType(String displayName) {
this.displayName = displayName; this.displayName = displayName;
@ -778,11 +622,12 @@ public class HashDbManager implements PropertyChangeListener {
INDEXING_DONE INDEXING_DONE
} }
private int handle; private static final long serialVersionUID = 1L;
private String hashSetName; private final int handle;
private final String hashSetName;
private boolean searchDuringIngest; private boolean searchDuringIngest;
private boolean sendIngestMessages; private boolean sendIngestMessages;
private KnownFilesType knownFilesType; private final KnownFilesType knownFilesType;
private boolean indexing; private boolean indexing;
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
@ -797,6 +642,8 @@ public class HashDbManager implements PropertyChangeListener {
/** /**
* Adds a listener for the events defined in HashDb.Event. * Adds a listener for the events defined in HashDb.Event.
*
* @param pcl
*/ */
public void addPropertyChangeListener(PropertyChangeListener pcl) { public void addPropertyChangeListener(PropertyChangeListener pcl) {
propertyChangeSupport.addPropertyChangeListener(pcl); propertyChangeSupport.addPropertyChangeListener(pcl);
@ -804,6 +651,8 @@ public class HashDbManager implements PropertyChangeListener {
/** /**
* Removes a listener for the events defined in HashDb.Event. * Removes a listener for the events defined in HashDb.Event.
*
* @param pcl
*/ */
public void removePropertyChangeListener(PropertyChangeListener pcl) { public void removePropertyChangeListener(PropertyChangeListener pcl) {
propertyChangeSupport.removePropertyChangeListener(pcl); propertyChangeSupport.removePropertyChangeListener(pcl);
@ -845,6 +694,8 @@ public class HashDbManager implements PropertyChangeListener {
* Indicates whether the hash database accepts updates. * Indicates whether the hash database accepts updates.
* *
* @return True if the database accepts updates, false otherwise. * @return True if the database accepts updates, false otherwise.
*
* @throws org.sleuthkit.datamodel.TskCoreException
*/ */
public boolean isUpdateable() throws TskCoreException { public boolean isUpdateable() throws TskCoreException {
return SleuthkitJNI.isUpdateableHashDatabase(this.handle); return SleuthkitJNI.isUpdateableHashDatabase(this.handle);
@ -956,6 +807,40 @@ public class HashDbManager implements PropertyChangeListener {
private void close() throws TskCoreException { private void close() throws TskCoreException {
SleuthkitJNI.closeHashDatabase(handle); SleuthkitJNI.closeHashDatabase(handle);
} }
@Override
public int hashCode() {
int code = 23;
code = 47 * code + Integer.hashCode(handle);
code = 47 * code + Objects.hashCode(this.hashSetName);
code = 47 * code + Objects.hashCode(this.propertyChangeSupport);
code = 47 * code + Objects.hashCode(this.knownFilesType);
return code;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final HashDb other = (HashDb) obj;
if (!Objects.equals(this.hashSetName, other.hashSetName)) {
return false;
}
if (this.searchDuringIngest != other.searchDuringIngest) {
return false;
}
if (this.sendIngestMessages != other.sendIngestMessages) {
return false;
}
if (this.knownFilesType != other.knownFilesType) {
return false;
}
return true;
}
} }
/** /**

View File

@ -0,0 +1,406 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 - 2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.hashdatabase;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import org.apache.commons.io.FileUtils;
import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.core.RuntimeProperties;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.datamodel.TskCoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Class to represent the settings to be serialized for hash lookup.
*/
final class HashLookupSettings implements Serializable {
private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; //NON-NLS
private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; //NON-NLS
private static final String SET_ELEMENT = "hash_set"; //NON-NLS
private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS
private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS
private static final String SEARCH_DURING_INGEST_ATTRIBUTE = "use_for_ingest"; //NON-NLS
private static final String SEND_INGEST_MESSAGES_ATTRIBUTE = "show_inbox_messages"; //NON-NLS
private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS
private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS
private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS
private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
private static final Logger logger = Logger.getLogger(HashDbManager.class.getName());
private static final long serialVersionUID = 1L;
private final List<HashDbInfo> hashDbInfoList;
/**
* Constructs a settings object to be serialized for hash lookups
*
* @param hashDbInfoList The list of hash db info.
*/
HashLookupSettings(List<HashDbInfo> hashDbInfoList) {
this.hashDbInfoList = hashDbInfoList;
}
/**
* Constructs a settings object to be serialized for hash lookups
*
* @param knownHashSets The list known hash sets for the settings.
* @param knownBadHashSets The list of known bad hash sets for the settings.
*/
HashLookupSettings(List<HashDbManager.HashDb> knownHashSets, List<HashDbManager.HashDb> knownBadHashSets) throws HashLookupSettingsException {
hashDbInfoList = new ArrayList<>();
this.addHashesToList(knownHashSets);
this.addHashesToList(knownBadHashSets);
}
/**
* Adds each HashDb to the settings.
*
* @param hashSetList The list of HashDb to add to the settings
*
* @throws * pacannot be obtained
*/
private void addHashesToList(List<HashDbManager.HashDb> hashSetList) throws HashLookupSettingsException {
for (HashDbManager.HashDb hashDb : hashSetList) {
try {
String dbPath;
if (hashDb.hasIndexOnly()) {
dbPath = hashDb.getIndexPath();
} else {
dbPath = hashDb.getDatabasePath();
}
hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), dbPath));
} catch (TskCoreException ex) {
throw new HashLookupSettingsException("Couldn't add hash database named: " + hashDb.getHashSetName(), ex);
}
}
}
/**
* Gets the list of hash db info that this settings contains
*
* @return The list of hash databse info
*/
List<HashDbInfo> getHashDbInfo() {
return hashDbInfoList;
}
/**
* Reads the settings from the disk.
*
* @return The settings object representing what was read.
*
* @throws HashLookupSettingsException When there is a problem reading the
* settings.
*/
static HashLookupSettings readSettings() throws HashLookupSettingsException {
File fileSetFile = new File(SERIALIZATION_FILE_PATH);
if (fileSetFile.exists()) {
return readSerializedSettings();
}
return readXmlSettings();
}
/**
* Reads the serialization settings from the disk
*
* @return Settings object representing what is saved in the serialization
* file.
*
* @throws HashLookupSettingsException If there's a problem importing the
* settings
*/
private static HashLookupSettings readSerializedSettings() throws HashLookupSettingsException {
try {
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) {
HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject();
return filesSetsSettings;
}
} catch (IOException | ClassNotFoundException ex) {
throw new HashLookupSettingsException("Could not read hash database settings.", ex);
}
}
/**
* Reads the xml settings from the disk
*
* @return Settings object representing what is saved in the xml file, or an
* empty settings if there is no xml file.
*
* @throws HashLookupSettingsException If there's a problem importing the
* settings
*/
private static HashLookupSettings readXmlSettings() throws HashLookupSettingsException {
File xmlFile = new File(configFilePath);
if (xmlFile.exists()) {
boolean updatedSchema = false;
// Open the XML document that implements the configuration file.
final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath);
if (doc == null) {
throw new HashLookupSettingsException("Could not open xml document.");
}
// Get the root element.
Element root = doc.getDocumentElement();
if (root == null) {
throw new HashLookupSettingsException("Error loading hash sets: invalid file format.");
}
// Get the hash set elements.
NodeList setsNList = root.getElementsByTagName(SET_ELEMENT);
int numSets = setsNList.getLength();
// Create HashDbInfo objects for each hash set element. Throws on malformed xml.
String attributeErrorMessage = "Missing %s attribute"; //NON-NLS
String elementErrorMessage = "Empty %s element"; //NON-NLS
List<String> hashSetNames = new ArrayList<>();
List<HashDbInfo> hashDbInfoList = new ArrayList<>();
for (int i = 0; i < numSets; ++i) {
Element setEl = (Element) setsNList.item(i);
String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE);
if (hashSetName.isEmpty()) {
throw new HashLookupSettingsException(String.format(attributeErrorMessage, SET_NAME_ATTRIBUTE));
}
// Handle configurations saved before duplicate hash set names were not permitted.
if (hashSetNames.contains(hashSetName)) {
int suffix = 0;
String newHashSetName;
do {
++suffix;
newHashSetName = hashSetName + suffix;
} while (hashSetNames.contains(newHashSetName));
logger.log(Level.INFO, "Duplicate hash set name " + hashSetName + " found. Replacing with " + newHashSetName + ".");
if (RuntimeProperties.coreComponentsAreActive()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.replacingDuplicateHashsetNameMsg",
hashSetName, newHashSetName),
NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.openHashDbErr"),
JOptionPane.ERROR_MESSAGE);
hashSetName = newHashSetName;
}
}
String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE);
if (knownFilesType.isEmpty()) {
throw new HashLookupSettingsException(String.format(attributeErrorMessage, SET_TYPE_ATTRIBUTE));
}
// Handle legacy known files types.
if (knownFilesType.equals("NSRL")) { //NON-NLS
knownFilesType = HashDbManager.HashDb.KnownFilesType.KNOWN.toString();
updatedSchema = true;
}
final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE);
if (searchDuringIngest.isEmpty()) {
throw new HashLookupSettingsException(String.format(attributeErrorMessage, SEND_INGEST_MESSAGES_ATTRIBUTE));
}
Boolean searchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest);
final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE);
if (searchDuringIngest.isEmpty()) {
throw new HashLookupSettingsException(String.format(attributeErrorMessage, SEND_INGEST_MESSAGES_ATTRIBUTE));
}
Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages);
String dbPath;
NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT);
if (pathsNList.getLength() > 0) {
Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one.
// Check for legacy path number attribute.
String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE);
if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) {
updatedSchema = true;
}
dbPath = pathEl.getTextContent();
if (dbPath.isEmpty()) {
throw new HashLookupSettingsException(String.format(elementErrorMessage, PATH_ELEMENT));
}
} else {
throw new HashLookupSettingsException(String.format(elementErrorMessage, PATH_ELEMENT));
}
hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType),
searchDuringIngestFlag, sendIngestMessagesFlag, dbPath));
hashSetNames.add(hashSetName);
}
if (updatedSchema) {
String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS
String messageBoxTitle = NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.msgBoxTitle.confFileFmtChanged");
String baseMessage = NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.baseMessage.updatedFormatHashDbConfig");
try {
FileUtils.copyFile(new File(configFilePath), new File(backupFilePath));
logger.log(Level.INFO, "Updated the schema, backup saved at: " + backupFilePath);
if (RuntimeProperties.coreComponentsAreActive()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.savedBackupOfOldConfigMsg",
baseMessage, backupFilePath),
messageBoxTitle,
JOptionPane.INFORMATION_MESSAGE);
}
} catch (IOException ex) {
logger.log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS
JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE);
}
HashLookupSettings settings;
settings = new HashLookupSettings(hashDbInfoList);
HashLookupSettings.writeSettings(settings);
}
return new HashLookupSettings(hashDbInfoList);
} else {
return new HashLookupSettings(new ArrayList<>());
}
}
/**
* Writes the given settings objects to the disk at the designated location
*
* @param settings The settings to be written
*
* @return Whether or not the settings were written successfully
*/
static boolean writeSettings(HashLookupSettings settings) {
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(SERIALIZATION_FILE_PATH))) {
out.writeObject(settings);
return true;
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not wtite hash database settings.");
return false;
}
}
/**
* Represents the serializable information within a hash lookup in order to
* be written to disk. Used to hand off information when loading and saving
* hash lookups.
*/
static final class HashDbInfo implements Serializable {
private static final long serialVersionUID = 1L;
private final String hashSetName;
private final HashDbManager.HashDb.KnownFilesType knownFilesType;
private final boolean searchDuringIngest;
private final boolean sendIngestMessages;
private final String path;
/**
* Constructs a HashDbInfo object
*
* @param hashSetName The name of the hash set
* @param knownFilesType The known files type
* @param searchDuringIngest Whether or not the db is searched during
* ingest
* @param sendIngestMessages Whether or not ingest messages are sent
* @param path The path to the db
*/
HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) {
this.hashSetName = hashSetName;
this.knownFilesType = knownFilesType;
this.searchDuringIngest = searchDuringIngest;
this.sendIngestMessages = sendIngestMessages;
this.path = path;
}
/**
* Gets the hash set name.
*
* @return The hash set name.
*/
String getHashSetName() {
return hashSetName;
}
/**
* Gets the known files type setting.
*
* @return The known files type setting.
*/
HashDbManager.HashDb.KnownFilesType getKnownFilesType() {
return knownFilesType;
}
/**
* Gets the search during ingest setting.
*
* @return The search during ingest setting.
*/
boolean getSearchDuringIngest() {
return searchDuringIngest;
}
/**
* Gets the send ingest messages setting.
*
* @return The send ingest messages setting.
*/
boolean getSendIngestMessages() {
return sendIngestMessages;
}
/**
* Gets the path.
*
* @return The path.
*/
String getPath() {
return path;
}
}
/**
* Used to translate more implementation-details-specific exceptions (which
* are logged by this class) into more generic exceptions for propagation to
* clients of the user-defined file types manager.
*/
static class HashLookupSettingsException extends Exception {
private static final long serialVersionUID = 1L;
HashLookupSettingsException(String message) {
super(message);
}
HashLookupSettingsException(String message, Throwable throwable) {
super(message, throwable);
}
}
}

View File

@ -3,7 +3,7 @@ Improvements:
- VMWare virtual machine files (vmdk) and Microsoft Virtual Hard Drives (vhd) can be added as data sources. - VMWare virtual machine files (vmdk) and Microsoft Virtual Hard Drives (vhd) can be added as data sources.
- New core ingest module detects vmdk and vhd files embedded in other data sources and adds them as data sources. - New core ingest module detects vmdk and vhd files embedded in other data sources and adds them as data sources.
- Text associated with artifacts posted to the blackboard is indexed and searched for keywords. - Text associated with artifacts posted to the blackboard is indexed and searched for keywords.
- Custom (user-defined) blackboard artifact and attribute types displayed in UI and included reports. - Custom (user-defined) blackboard artifact and attribute types displayed in UI and included in reports.
- File size and MIME type conditions can be specified for interesting files rules. - File size and MIME type conditions can be specified for interesting files rules.
- File size and MIME type conditions can be specified for file search by attributes. - File size and MIME type conditions can be specified for file search by attributes.
- Local/GMT time preference is used in reports. - Local/GMT time preference is used in reports.