diff --git a/FileExtMismatch/build.xml b/FileExtMismatch/build.xml new file mode 100644 index 0000000000..90f199456e --- /dev/null +++ b/FileExtMismatch/build.xml @@ -0,0 +1,8 @@ + + + + + + Builds, tests, and runs the project org.sleuthkit.autopsy.fileextmismatch. + + diff --git a/FileExtMismatch/manifest.mf b/FileExtMismatch/manifest.mf new file mode 100644 index 0000000000..c1678923ea --- /dev/null +++ b/FileExtMismatch/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.sleuthkit.autopsy.fileextmismatch/3 +OpenIDE-Module-Implementation-Version: 1 +OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/fileextmismatch/Bundle.properties + diff --git a/FileExtMismatch/nbproject/build-impl.xml b/FileExtMismatch/nbproject/build-impl.xml new file mode 100644 index 0000000000..40c37cb50f --- /dev/null +++ b/FileExtMismatch/nbproject/build-impl.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FileExtMismatch/nbproject/platform.properties b/FileExtMismatch/nbproject/platform.properties new file mode 100644 index 0000000000..a9fa87f749 --- /dev/null +++ b/FileExtMismatch/nbproject/platform.properties @@ -0,0 +1,120 @@ +branding.token=autopsy +netbeans-plat-version=7.3.1 +suite.dir=${basedir} +nbplatform.active.dir=${suite.dir}/netbeans-plat/${netbeans-plat-version} +harness.dir=${nbplatform.active.dir}/harness +bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/netbeans/harness/tasks.jar +autoupdate.catalog.url=http://dlc.sun.com.edgesuite.net/netbeans/updates/${netbeans-plat-version}/uc/final/distribution/catalog.xml.gz +cluster.path=\ + ${nbplatform.active.dir}/harness:\ + ${nbplatform.active.dir}/java:\ + ${nbplatform.active.dir}/platform +disabled.modules=\ + org.apache.tools.ant.module,\ + org.netbeans.api.debugger.jpda,\ + org.netbeans.api.java,\ + org.netbeans.lib.nbjavac,\ + org.netbeans.libs.cglib,\ + org.netbeans.libs.javacapi,\ + org.netbeans.libs.javacimpl,\ + org.netbeans.libs.springframework,\ + org.netbeans.modules.ant.browsetask,\ + org.netbeans.modules.ant.debugger,\ + org.netbeans.modules.ant.freeform,\ + org.netbeans.modules.ant.grammar,\ + org.netbeans.modules.ant.kit,\ + org.netbeans.modules.beans,\ + org.netbeans.modules.classfile,\ + org.netbeans.modules.dbschema,\ + org.netbeans.modules.debugger.jpda,\ + org.netbeans.modules.debugger.jpda.ant,\ + org.netbeans.modules.debugger.jpda.kit,\ + org.netbeans.modules.debugger.jpda.projects,\ + org.netbeans.modules.debugger.jpda.ui,\ + org.netbeans.modules.debugger.jpda.visual,\ + org.netbeans.modules.findbugs.installer,\ + org.netbeans.modules.form,\ + org.netbeans.modules.form.binding,\ + org.netbeans.modules.form.j2ee,\ + org.netbeans.modules.form.kit,\ + org.netbeans.modules.form.nb,\ + org.netbeans.modules.form.refactoring,\ + org.netbeans.modules.hibernate,\ + org.netbeans.modules.hibernatelib,\ + org.netbeans.modules.hudson.ant,\ + org.netbeans.modules.hudson.maven,\ + org.netbeans.modules.i18n,\ + org.netbeans.modules.i18n.form,\ + org.netbeans.modules.j2ee.core.utilities,\ + org.netbeans.modules.j2ee.eclipselink,\ + org.netbeans.modules.j2ee.eclipselinkmodelgen,\ + org.netbeans.modules.j2ee.jpa.refactoring,\ + org.netbeans.modules.j2ee.jpa.verification,\ + org.netbeans.modules.j2ee.metadata,\ + org.netbeans.modules.j2ee.metadata.model.support,\ + org.netbeans.modules.j2ee.persistence,\ + org.netbeans.modules.j2ee.persistence.kit,\ + org.netbeans.modules.j2ee.persistenceapi,\ + org.netbeans.modules.java.api.common,\ + org.netbeans.modules.java.debug,\ + org.netbeans.modules.java.editor,\ + org.netbeans.modules.java.editor.lib,\ + org.netbeans.modules.java.examples,\ + org.netbeans.modules.java.freeform,\ + org.netbeans.modules.java.guards,\ + org.netbeans.modules.java.helpset,\ + org.netbeans.modules.java.hints,\ + org.netbeans.modules.java.hints.declarative,\ + org.netbeans.modules.java.hints.declarative.test,\ + org.netbeans.modules.java.hints.legacy.spi,\ + org.netbeans.modules.java.hints.test,\ + org.netbeans.modules.java.hints.ui,\ + org.netbeans.modules.java.j2seplatform,\ + org.netbeans.modules.java.j2seproject,\ + org.netbeans.modules.java.kit,\ + org.netbeans.modules.java.lexer,\ + org.netbeans.modules.java.navigation,\ + org.netbeans.modules.java.platform,\ + org.netbeans.modules.java.preprocessorbridge,\ + org.netbeans.modules.java.project,\ + org.netbeans.modules.java.source,\ + org.netbeans.modules.java.source.ant,\ + org.netbeans.modules.java.source.queries,\ + org.netbeans.modules.java.source.queriesimpl,\ + org.netbeans.modules.java.sourceui,\ + org.netbeans.modules.java.testrunner,\ + org.netbeans.modules.javadoc,\ + org.netbeans.modules.javawebstart,\ + org.netbeans.modules.junit,\ + org.netbeans.modules.maven,\ + org.netbeans.modules.maven.checkstyle,\ + org.netbeans.modules.maven.coverage,\ + org.netbeans.modules.maven.embedder,\ + org.netbeans.modules.maven.grammar,\ + org.netbeans.modules.maven.graph,\ + org.netbeans.modules.maven.hints,\ + org.netbeans.modules.maven.indexer,\ + org.netbeans.modules.maven.junit,\ + org.netbeans.modules.maven.kit,\ + org.netbeans.modules.maven.model,\ + org.netbeans.modules.maven.osgi,\ + org.netbeans.modules.maven.persistence,\ + org.netbeans.modules.maven.refactoring,\ + org.netbeans.modules.maven.repository,\ + org.netbeans.modules.maven.search,\ + org.netbeans.modules.maven.spring,\ + org.netbeans.modules.projectimport.eclipse.core,\ + org.netbeans.modules.projectimport.eclipse.j2se,\ + org.netbeans.modules.refactoring.java,\ + org.netbeans.modules.spellchecker.bindings.java,\ + org.netbeans.modules.spring.beans,\ + org.netbeans.modules.testng,\ + org.netbeans.modules.testng.ant,\ + org.netbeans.modules.testng.maven,\ + org.netbeans.modules.websvc.jaxws21,\ + org.netbeans.modules.websvc.jaxws21api,\ + org.netbeans.modules.websvc.saas.codegen.java,\ + org.netbeans.modules.xml.jaxb,\ + org.netbeans.modules.xml.tools.java,\ + org.netbeans.spi.java.hints + diff --git a/FileExtMismatch/nbproject/project.properties b/FileExtMismatch/nbproject/project.properties new file mode 100644 index 0000000000..21d3761899 --- /dev/null +++ b/FileExtMismatch/nbproject/project.properties @@ -0,0 +1,3 @@ +javac.source=1.7 +javac.compilerargs=-Xlint -Xlint:-serial +spec.version.base=1.3 diff --git a/FileExtMismatch/nbproject/project.xml b/FileExtMismatch/nbproject/project.xml new file mode 100644 index 0000000000..23fa0b7529 --- /dev/null +++ b/FileExtMismatch/nbproject/project.xml @@ -0,0 +1,115 @@ + + + org.netbeans.modules.apisupport.project + + + org.sleuthkit.autopsy.fileextmismatch + + + + org.netbeans.api.progress + + + + 1 + 1.32.1 + + + + org.netbeans.modules.options.api + + + + 1 + 1.31.2 + + + + org.openide.awt + + + + 7.55.1 + + + + org.openide.dialogs + + + + 7.28.1 + + + + org.openide.explorer + + + + 6.50.3 + + + + org.openide.nodes + + + + 7.33.2 + + + + org.openide.util + + + + 8.29.3 + + + + org.openide.util.lookup + + + + 8.19.1 + + + + org.openide.windows + + + + 6.60.1 + + + + org.sleuthkit.autopsy.core + + + + 9 + 7.0 + + + + org.sleuthkit.autopsy.corelibs + + + + 3 + 1.1 + + + + org.sleuthkit.autopsy.filetypeid + + + + 1.0 + + + + + org.sleuthkit.autopsy.fileextmismatch + + + + diff --git a/FileExtMismatch/nbproject/suite.properties b/FileExtMismatch/nbproject/suite.properties new file mode 100644 index 0000000000..29d7cc9bd6 --- /dev/null +++ b/FileExtMismatch/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/AddFileExtensionAction.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/AddFileExtensionAction.java new file mode 100644 index 0000000000..b0e8ea28fb --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/AddFileExtensionAction.java @@ -0,0 +1,60 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2014 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; + +/** + * Do the context menu action for adding a new filename extension to + * the mismatch list for the MIME type of the selected node. + */ +public class AddFileExtensionAction extends AbstractAction { + private String extStr; + private String mimeTypeStr; + + public AddFileExtensionAction(String menuItemStr, String extStr, String mimeTypeStr) { + super(menuItemStr); + this.mimeTypeStr = mimeTypeStr; + this.extStr = extStr; + } + + @Override + public void actionPerformed(ActionEvent event) { + HashMap editableMap = FileExtMismatchXML.getDefault().load(); + ArrayList editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(mimeTypeStr))); + editedExtensions.add(extStr); + + // Old array will be replaced by new array for this key + editableMap.put(mimeTypeStr, editedExtensions.toArray(new String[0])); + + if (!FileExtMismatchXML.getDefault().save(editableMap)) { + //error + JOptionPane.showMessageDialog(null, "Writing XML configuration file failed.", "Add Mismatch Extension Error", JOptionPane.ERROR_MESSAGE); + } // else //in the future we might want to update the statusbar to give feedback to the user + + } + +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/Bundle.properties b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/Bundle.properties new file mode 100644 index 0000000000..0172466a3d --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/Bundle.properties @@ -0,0 +1,18 @@ +OpenIDE-Module-Name=FileExtMismatch +FileExtMismatchSimpleConfigPanel.skipKnownCheckBox.text=Skip Known Files (NSRL) +FileExtMismatchSimpleConfigPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of mismatch detection. +FileExtMismatchConfigPanel.extHeaderLabel.text=Allowed Extensions: +FileExtMismatchConfigPanel.userExtTextField.text= +FileExtMismatchConfigPanel.addExtButton.text=Add Extension +FileExtMismatchConfigPanel.removeExtButton.text=Remove Selected Extension +FileExtMismatchConfigPanel.saveButton.text=Save Configuration +FileExtMismatchConfigPanel.jLabel1.text=File Types: +FileExtMismatchConfigPanel.removeTypeButton.text=Remove Selected Type +FileExtMismatchConfigPanel.addTypeButton.text=Add Type +FileExtMismatchConfigPanel.userTypeTextField.text= +FileExtMismatchConfigPanel.extErrorLabel.text=\ +FileExtMismatchConfigPanel.mimeErrLabel.text=\ +FileExtMismatchConfigPanel.mimeRemoveErrLabel.text=\ +FileExtMismatchConfigPanel.extRemoveErrLabel.text=\ +FileExtMismatchConfigPanel.saveMsgLabel.text=\ +FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text=Skip Files Without Extensions diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.form b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.form new file mode 100644 index 0000000000..9ae257607d --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.form @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.java new file mode 100644 index 0000000000..2b2ca04ae1 --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchConfigPanel.java @@ -0,0 +1,704 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.logging.Level; +import javax.swing.JOptionPane; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import org.sleuthkit.autopsy.corecomponents.OptionsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.filetypeid.FileTypeIdIngestModule; + +/** + * Container panel for File Extension Mismatch Ingest Module advanced configuration options + */ +public final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements OptionsPanel { + private static Logger logger = Logger.getLogger(FileExtMismatchConfigPanel.class.getName()); + private HashMap editableMap = new HashMap<>(); + private ArrayList mimeList = null; + private ArrayList currentExtensions = null; + private MimeTableModel mimeTableModel; + private ExtTableModel extTableModel; + private final String EXT_HEADER_LABEL = "Allowed Extensions for "; + private String selectedMime = ""; + private String selectedExt = ""; + ListSelectionModel lsm = null; + + public FileExtMismatchConfigPanel() { + mimeTableModel = new MimeTableModel(); + extTableModel = new ExtTableModel(); + + initComponents(); + customizeComponents(); + } + + private void customizeComponents() { + setName("Advanced File Extension Mismatch Configuration"); + + // Handle selections on the left table + lsm = mimeTable.getSelectionModel(); + lsm.addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); + if (!listSelectionModel.isSelectionEmpty()) { + int index = listSelectionModel.getMinSelectionIndex(); + listSelectionModel.setSelectionInterval(index, index); + + selectedMime = mimeList.get(index); + String labelStr = EXT_HEADER_LABEL + selectedMime + ":"; + if (labelStr.length() > 80) { + labelStr = labelStr.substring(0, 80); + } + extHeaderLabel.setText(labelStr); + updateExtList(); + + extTableModel.resync(); + //initButtons(); + } else { + selectedMime = ""; + currentExtensions = null; + extTableModel.resync(); + } + + clearErrLabels(); + } + }); + + // Handle selections on the right table + ListSelectionModel extLsm = extTable.getSelectionModel(); + extLsm.addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); + if (!listSelectionModel.isSelectionEmpty()) { + int index = listSelectionModel.getMinSelectionIndex(); + listSelectionModel.setSelectionInterval(index, index); + + selectedExt = currentExtensions.get(index); + } else { + selectedExt = ""; + } + + extRemoveErrLabel.setText(" "); + + } + }); + + } + + private void clearErrLabels() { + mimeErrLabel.setText(" "); + mimeRemoveErrLabel.setText(" "); + extRemoveErrLabel.setText(" "); + extErrorLabel.setText(" "); + saveMsgLabel.setText(" "); + } + + /** + * 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. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + saveButton = new javax.swing.JButton(); + jSplitPane1 = new javax.swing.JSplitPane(); + mimePanel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + mimeTable = new javax.swing.JTable(); + userTypeTextField = new javax.swing.JTextField(); + addTypeButton = new javax.swing.JButton(); + removeTypeButton = new javax.swing.JButton(); + mimeErrLabel = new javax.swing.JLabel(); + mimeRemoveErrLabel = new javax.swing.JLabel(); + extensionPanel = new javax.swing.JPanel(); + userExtTextField = new javax.swing.JTextField(); + addExtButton = new javax.swing.JButton(); + jScrollPane3 = new javax.swing.JScrollPane(); + extTable = new javax.swing.JTable(); + removeExtButton = new javax.swing.JButton(); + extHeaderLabel = new javax.swing.JLabel(); + extErrorLabel = new javax.swing.JLabel(); + extRemoveErrLabel = new javax.swing.JLabel(); + saveMsgLabel = new javax.swing.JLabel(); + + saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/fileextmismatch/save16.png"))); // NOI18N + saveButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.saveButton.text")); // NOI18N + saveButton.setEnabled(false); + saveButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveButtonActionPerformed(evt); + } + }); + + jSplitPane1.setDividerLocation(430); + + jLabel1.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.jLabel1.text")); // NOI18N + + mimeTable.setModel(mimeTableModel); + jScrollPane2.setViewportView(mimeTable); + + userTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.userTypeTextField.text")); // NOI18N + userTypeTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + userTypeTextFieldFocusGained(evt); + } + }); + + addTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.addTypeButton.text")); // NOI18N + addTypeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addTypeButtonActionPerformed(evt); + } + }); + + removeTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.removeTypeButton.text")); // NOI18N + removeTypeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + removeTypeButtonActionPerformed(evt); + } + }); + + mimeErrLabel.setForeground(new java.awt.Color(255, 0, 0)); + mimeErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.mimeErrLabel.text")); // NOI18N + + mimeRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.mimeRemoveErrLabel.text")); // NOI18N + + javax.swing.GroupLayout mimePanelLayout = new javax.swing.GroupLayout(mimePanel); + mimePanel.setLayout(mimePanelLayout); + mimePanelLayout.setHorizontalGroup( + mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(mimePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(mimePanelLayout.createSequentialGroup() + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addGroup(mimePanelLayout.createSequentialGroup() + .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(addTypeButton)) + .addComponent(removeTypeButton)) + .addGap(0, 196, Short.MAX_VALUE)) + .addComponent(mimeErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(mimeRemoveErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + mimePanelLayout.setVerticalGroup( + mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(mimePanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addTypeButton)) + .addGap(3, 3, 3) + .addComponent(mimeErrLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(removeTypeButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(mimeRemoveErrLabel) + .addContainerGap(45, Short.MAX_VALUE)) + ); + + jSplitPane1.setLeftComponent(mimePanel); + + userExtTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.userExtTextField.text")); // NOI18N + userExtTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + userExtTextFieldFocusGained(evt); + } + }); + + addExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.addExtButton.text")); // NOI18N + addExtButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addExtButtonActionPerformed(evt); + } + }); + + extTable.setModel(extTableModel); + jScrollPane3.setViewportView(extTable); + + removeExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.removeExtButton.text")); // NOI18N + removeExtButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + removeExtButtonActionPerformed(evt); + } + }); + + extHeaderLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extHeaderLabel.text")); // NOI18N + + extErrorLabel.setForeground(new java.awt.Color(255, 0, 0)); + extErrorLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extErrorLabel.text")); // NOI18N + + extRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extRemoveErrLabel.text")); // NOI18N + + javax.swing.GroupLayout extensionPanelLayout = new javax.swing.GroupLayout(extensionPanel); + extensionPanel.setLayout(extensionPanelLayout); + extensionPanelLayout.setHorizontalGroup( + extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(extensionPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(extHeaderLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(extensionPanelLayout.createSequentialGroup() + .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(removeExtButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(extensionPanelLayout.createSequentialGroup() + .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(addExtButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(0, 66, Short.MAX_VALUE)) + .addComponent(extErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(extRemoveErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + extensionPanelLayout.setVerticalGroup( + extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, extensionPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(extHeaderLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 285, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addExtButton)) + .addGap(2, 2, 2) + .addComponent(extErrorLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(removeExtButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(extRemoveErrLabel) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jSplitPane1.setRightComponent(extensionPanel); + + saveMsgLabel.setForeground(new java.awt.Color(0, 0, 255)); + saveMsgLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.saveMsgLabel.text")); // NOI18N + + 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) + .addComponent(jSplitPane1) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(saveButton, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(saveMsgLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(saveButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(saveMsgLabel) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + // Add a user-provided filename extension string to the selecte mimetype + private void addExtButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addExtButtonActionPerformed + String newExt = userExtTextField.getText(); + if (newExt.isEmpty()) { + extErrorLabel.setForeground(Color.red); + extErrorLabel.setText("Extension text is empty!"); + return; + } + + if (selectedMime.isEmpty()) { + extErrorLabel.setForeground(Color.red); + extErrorLabel.setText("No MIME type selected!"); + return; + } + + if (currentExtensions.contains(newExt)) { + extErrorLabel.setForeground(Color.red); + extErrorLabel.setText("Extension already exists!"); + return; + } + + ArrayList editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(selectedMime))); + editedExtensions.add(newExt); + + // Old array will be replaced by new array for this key + editableMap.put(selectedMime, editedExtensions.toArray(new String[0])); + + // Refresh table + updateExtList(); + extTableModel.resync(); + + // user feedback for successful add + extErrorLabel.setForeground(Color.blue); + extErrorLabel.setText("Extension " + newExt + " added."); + extRemoveErrLabel.setText(" "); + userExtTextField.setText(""); + setIsModified(); + }//GEN-LAST:event_addExtButtonActionPerformed + + private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed + store(); + }//GEN-LAST:event_saveButtonActionPerformed + + private void addTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTypeButtonActionPerformed + String newMime = userTypeTextField.getText(); + if (newMime.isEmpty()) { + mimeErrLabel.setForeground(Color.red); + mimeErrLabel.setText("MIME type text is empty!"); + return; + } + + if (mimeList.contains(newMime)) { + mimeErrLabel.setForeground(Color.red); + mimeErrLabel.setText("MIME type already exists!"); + return; + } + + if (!FileTypeIdIngestModule.isMimeTypeDetectable(newMime)) { + mimeErrLabel.setForeground(Color.red); + mimeErrLabel.setText("MIME type is not detectable by this module."); + return; + } + + editableMap.put(newMime, new String[0]); + + // Refresh table + updateMimeList(); + mimeTableModel.resync(); + + // user feedback for successful add + //selectByMimeString(newMime); + mimeErrLabel.setForeground(Color.blue); + mimeErrLabel.setText("MIME type " + newMime + " added."); + mimeRemoveErrLabel.setText(" "); + userTypeTextField.setText(""); + setIsModified(); + }//GEN-LAST:event_addTypeButtonActionPerformed + + private void userExtTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_userExtTextFieldFocusGained + extErrorLabel.setText(" "); //space so Swing doesn't mess up vertical spacing + }//GEN-LAST:event_userExtTextFieldFocusGained + + private void userTypeTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_userTypeTextFieldFocusGained + mimeErrLabel.setText(" "); //space so Swing doesn't mess up vertical spacing + }//GEN-LAST:event_userTypeTextFieldFocusGained + + private void removeTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeTypeButtonActionPerformed + if (selectedMime.isEmpty()) { + mimeRemoveErrLabel.setForeground(Color.red); + mimeRemoveErrLabel.setText("No MIME type selected!"); + return; + } + + editableMap.remove(selectedMime); + String deadMime = selectedMime; + + // Refresh table + updateMimeList(); + mimeTableModel.resync(); + + // user feedback for successful add + mimeRemoveErrLabel.setForeground(Color.blue); + mimeRemoveErrLabel.setText("MIME type " + deadMime + " deleted."); + setIsModified(); + }//GEN-LAST:event_removeTypeButtonActionPerformed + + private void removeExtButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeExtButtonActionPerformed + if (selectedExt.isEmpty()) { + extRemoveErrLabel.setForeground(Color.red); + extRemoveErrLabel.setText("No extension selected!"); + return; + } + + if (selectedMime.isEmpty()) { + extErrorLabel.setForeground(Color.red); + extErrorLabel.setText("No MIME type selected!"); + return; + } + + ArrayList editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(selectedMime))); + editedExtensions.remove(selectedExt); + String deadExt = selectedExt; + + // Old array will be replaced by new array for this key + editableMap.put(selectedMime, editedExtensions.toArray(new String[0])); + + // Refresh tables + updateExtList(); + extTableModel.resync(); + + // user feedback for successful add + extRemoveErrLabel.setForeground(Color.blue); + extRemoveErrLabel.setText("Extension " + deadExt + " deleted."); + setIsModified(); + }//GEN-LAST:event_removeExtButtonActionPerformed + + private void updateMimeList() { + mimeList = new ArrayList<>(editableMap.keySet()); + if (mimeList.size() > 0) { + Collections.sort(mimeList); + } + } + + private void updateExtList() { + String[] temp = editableMap.get(selectedMime); + if (temp != null) { + currentExtensions = new ArrayList<>(Arrays.asList(temp)); + if (temp.length > 0) { + Collections.sort(currentExtensions); + } + } else { + currentExtensions = null; + } + } + + @Override + public void load() { + // Load the XML into a buffer that the user can modify. They can choose + // to save it back to the file after making changes. + editableMap = FileExtMismatchXML.getDefault().load(); + updateMimeList(); + updateExtList(); + } + + @Override + public void store() { + if (FileExtMismatchXML.getDefault().save(editableMap)) { + mimeErrLabel.setText(" "); + mimeRemoveErrLabel.setText(" "); + extRemoveErrLabel.setText(" "); + extErrorLabel.setText(" "); + + saveMsgLabel.setText("Saved."); + saveButton.setEnabled(false); + } else { + //error + JOptionPane.showMessageDialog(this, "Writing XML configuration file failed.", "Save Error", JOptionPane.ERROR_MESSAGE); + } + } + + private void setIsModified() { + saveButton.setEnabled(true); + saveMsgLabel.setText(" "); + } + + public void cancel() { + clearErrLabels(); + load(); // The next time this panel is opened, we want it to be fresh + } + + public void ok() { + // if data is unsaved + if (saveButton.isEnabled()) { + int choice = JOptionPane.showConfirmDialog(this, "Would you like to save configuration changes?", "Unsaved Changes", JOptionPane.YES_NO_OPTION); + if (choice == JOptionPane.YES_OPTION) { + store(); + } + } + clearErrLabels(); + load(); // The next time this panel is opened, we want it to be fresh + } + + boolean valid() { + return true; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addExtButton; + private javax.swing.JButton addTypeButton; + private javax.swing.JLabel extErrorLabel; + private javax.swing.JLabel extHeaderLabel; + private javax.swing.JLabel extRemoveErrLabel; + private javax.swing.JTable extTable; + private javax.swing.JPanel extensionPanel; + private javax.swing.JLabel jLabel1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JLabel mimeErrLabel; + private javax.swing.JPanel mimePanel; + private javax.swing.JLabel mimeRemoveErrLabel; + private javax.swing.JTable mimeTable; + private javax.swing.JButton removeExtButton; + private javax.swing.JButton removeTypeButton; + private javax.swing.JButton saveButton; + private javax.swing.JLabel saveMsgLabel; + private javax.swing.JTextField userExtTextField; + private javax.swing.JTextField userTypeTextField; + // End of variables declaration//GEN-END:variables + + private class MimeTableModel extends AbstractTableModel { + + @Override + public int getColumnCount() { + return 1; + } + + @Override + public int getRowCount() { + return editableMap == null ? 0 : editableMap.size(); + } + + @Override + public String getColumnName(int column) { + String colName = null; + + switch (column) { + case 0: + colName = "MIME Type"; + break; + default: + ; + + } + return colName; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + Object ret = null; + if ((mimeList == null) || (rowIndex > mimeList.size())) { + return ""; + } + String word = mimeList.get(rowIndex); + switch (columnIndex) { + case 0: + ret = (Object) word; + break; + default: + logger.log(Level.SEVERE, "Invalid table column index: " + columnIndex); + break; + } + return ret; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + } + + @Override + public Class> getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + + void resync() { + fireTableDataChanged(); + } + } + + private class ExtTableModel extends AbstractTableModel { + + @Override + public int getColumnCount() { + return 1; + } + + @Override + public int getRowCount() { + return currentExtensions == null ? 0 : currentExtensions.size(); + } + + @Override + public String getColumnName(int column) { + String colName = null; + + switch (column) { + case 0: + colName = "Extension"; + break; + default: + ; + + } + return colName; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + Object ret = null; + + if ((currentExtensions == null) || (currentExtensions.size() == 0) || (rowIndex > currentExtensions.size())) { + return ""; + } + String word = currentExtensions.get(rowIndex); + switch (columnIndex) { + case 0: + ret = (Object) word; + break; + default: + logger.log(Level.SEVERE, "Invalid table column index: " + columnIndex); + break; + } + return ret; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + } + + @Override + public Class> getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + + void resync() { + fireTableDataChanged(); + } + } + +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchContextMenuActionsProvider.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchContextMenuActionsProvider.java new file mode 100644 index 0000000000..2d6b871321 --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchContextMenuActionsProvider.java @@ -0,0 +1,127 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2014 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; +import javax.swing.Action; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.Utilities; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.ingest.IngestConfigurator; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * This creates a single context menu item for adding a new filename extension to + * the mismatch list for the MIME type of the selected node. + */ +@ServiceProvider(service = ContextMenuActionsProvider.class) +public class FileExtMismatchContextMenuActionsProvider implements ContextMenuActionsProvider { + @Override + public List getActions() { + ArrayList actions = new ArrayList<>(); + + // Ignore if file ingest is in progress. + IngestConfigurator ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class); + if (ingestConfigurator != null && !ingestConfigurator.isIngestRunning()) { + + final Collection extends BlackboardArtifact> selectedArts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class); + + // Prevent multiselect + if (selectedArts.size() == 1) { + + for (BlackboardArtifact nodeArt : selectedArts) { + + // Only for mismatch results + if (nodeArt.getArtifactTypeName().equals("TSK_EXT_MISMATCH_DETECTED")) { + String mimeTypeStr = ""; + String extStr = ""; + + AbstractFile af = null; + try { + af = nodeArt.getSleuthkitCase().getAbstractFileById(nodeArt.getObjectID()); + } catch (TskCoreException ex) { + Logger.getLogger(FileExtMismatchContextMenuActionsProvider.class.getName()).log(Level.SEVERE, "Error getting file by id", ex); + } + + if (af != null) { + try { + int i = af.getName().lastIndexOf("."); + if ((i > -1) && ((i + 1) < af.getName().length())) { + extStr = af.getName().substring(i + 1).toLowerCase(); + } + + ArrayList artList = af.getAllArtifacts(); + for (BlackboardArtifact art : artList) { + List atrList = art.getAttributes(); + for (BlackboardAttribute att : atrList) { + if (att.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()) { + mimeTypeStr = att.getValueString(); + break; + } + } + if (!mimeTypeStr.isEmpty()) { + break; + } + } + } catch (TskCoreException ex) { + Logger.getLogger(FileExtMismatchContextMenuActionsProvider.class.getName()).log(Level.SEVERE, "Error looking up blackboard attributes", ex); + } + + if (!extStr.isEmpty() && !mimeTypeStr.isEmpty()) { + // Limit max size so the context window doesn't get ridiculously wide + if (extStr.length() > 10) { + extStr = extStr.substring(0, 9); + } + if (mimeTypeStr.length() > 40) { + mimeTypeStr = mimeTypeStr.substring(0, 39); + } + String menuItemStr = "Add extension " + extStr + " as matching MIME type " + mimeTypeStr; + actions.add(new AddFileExtensionAction(menuItemStr, extStr, mimeTypeStr)); + + // Check if already added + HashMap editableMap = FileExtMismatchXML.getDefault().load(); + ArrayList editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(mimeTypeStr))); + if (editedExtensions.contains(extStr)) { + // Informs the user that they have already added this extension to this MIME type + actions.get(0).setEnabled(false); + } + + } + } + } + } + } + } + + return actions; + } +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchIngestModule.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchIngestModule.java new file mode 100644 index 0000000000..9037b9756c --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchIngestModule.java @@ -0,0 +1,267 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.Version; +import org.sleuthkit.autopsy.ingest.IngestMessage; +import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile; +import org.sleuthkit.autopsy.ingest.IngestModuleInit; +import org.sleuthkit.autopsy.ingest.IngestServices; +import org.sleuthkit.autopsy.ingest.ModuleDataEvent; +import org.sleuthkit.autopsy.ingest.PipelineContext; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.TskData.FileKnown; +import org.sleuthkit.datamodel.TskException; + +/** + * Flags mismatched filename extensions based on file signature. + */ +public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile { + private static FileExtMismatchIngestModule defaultInstance = null; + private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName()); + public static final String MODULE_NAME = "File Extension Mismatch Detection"; + public static final String MODULE_DESCRIPTION = "Flags mismatched filename extensions based on file signature."; + public static final String MODULE_VERSION = Version.getVersion(); + private static final String ART_NAME = "TSK_MISMATCH"; + + private static long processTime = 0; + private static int messageId = 0; + private static long numFiles = 0; + private static boolean skipKnown = false; + private static boolean skipNoExt = true; + + private int attrId = -1; + private int attrId2 = -1; + private FileExtMismatchSimpleConfigPanel simpleConfigPanel; + private FileExtMismatchConfigPanel advancedConfigPanel; + private IngestServices services; + private HashMap SigTypeToExtMap = new HashMap<>(); + private String currActualExt = ""; + private String currActualSigType = ""; + + // Private to ensure Singleton status + private FileExtMismatchIngestModule() { + + } + + // File-level ingest modules are currently singleton -- this is required + public static synchronized FileExtMismatchIngestModule getDefault() { + //defaultInstance is a private static class variable + if (defaultInstance == null) { + defaultInstance = new FileExtMismatchIngestModule(); + } + return defaultInstance; + } + + + @Override + public void init(IngestModuleInit initContext) { + services = IngestServices.getDefault(); + + // Load mapping + FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault(); + SigTypeToExtMap = xmlLoader.load(); + + } + + @Override + public ProcessResult process(PipelineContext pipelineContext, AbstractFile abstractFile) { + // skip non-files + if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || + (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) { + + return ProcessResult.OK; + } + + if (skipKnown && (abstractFile.getKnown() == FileKnown.KNOWN)) { + return ProcessResult.OK; + } + + try + { + long startTime = System.currentTimeMillis(); + + boolean flag = compareSigTypeToExt(abstractFile); + + processTime += (System.currentTimeMillis() - startTime); + numFiles++; + + if (flag) { + // add artifact + BlackboardArtifact bart = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED); + + services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED, Collections.singletonList(bart))); + } + return ProcessResult.OK; + } catch (TskException ex) { + logger.log(Level.WARNING, "Error matching file signature", ex); + return ProcessResult.ERROR; + } + } + + private boolean compareSigTypeToExt(AbstractFile abstractFile) { + try { + currActualExt = ""; + int i = abstractFile.getName().lastIndexOf("."); + if ((i > -1) && ((i + 1) < abstractFile.getName().length())) { + currActualExt = abstractFile.getName().substring(i + 1).toLowerCase(); + } + + // If we are skipping names with no extension + if (skipNoExt && currActualExt.isEmpty()) { + return false; + } + + // find file_sig value. + // getArtifacts by type doesn't seem to work, so get all artifacts + ArrayList artList = abstractFile.getAllArtifacts(); + + for (BlackboardArtifact art : artList) { + List atrList = art.getAttributes(); + for (BlackboardAttribute att : atrList) { + if (att.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()) { + currActualSigType = att.getValueString(); + + //get known allowed values from the map for this type + String[] slist = SigTypeToExtMap.get(att.getValueString()); + if (slist != null) { + List allowedExtList = Arrays.asList(slist); + + // see if the filename ext is in the allowed list + if (allowedExtList != null) { + for (String e : allowedExtList) { + if (e.equals(currActualExt)) { + return false; + } + } + return true; //potential mismatch + } + } + } + } + } + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + return false; + } + + @Override + public void complete() { + StringBuilder detailsSb = new StringBuilder(); + //details + detailsSb.append(""); + + detailsSb.append(""+MODULE_DESCRIPTION+""); + + detailsSb.append("Total Processing Time").append(processTime).append("\n"); + detailsSb.append("Total Files Processed").append(numFiles).append("\n"); + detailsSb.append(""); + + services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, this, "File Extension Mismatch Results", detailsSb.toString())); + } + + @Override + public void stop() { + //do nothing + } + + @Override + public String getName() { + return MODULE_NAME; + } + + @Override + public String getDescription() { + return MODULE_DESCRIPTION; + } + + @Override + public String getVersion() { + return MODULE_VERSION; + } + + @Override + public boolean hasSimpleConfiguration() { + return true; + } + + @Override + public boolean hasAdvancedConfiguration() { + return true; + } + + @Override + public javax.swing.JPanel getSimpleConfiguration(String context) { + if (simpleConfigPanel == null) { + simpleConfigPanel = new FileExtMismatchSimpleConfigPanel(); + } + + return simpleConfigPanel; + } + + @Override + public javax.swing.JPanel getAdvancedConfiguration(String context) { + getPanel().load(); + return getPanel(); + } + + private FileExtMismatchConfigPanel getPanel() { + if (advancedConfigPanel == null) { + advancedConfigPanel = new FileExtMismatchConfigPanel(); + } + return advancedConfigPanel; + } + + @Override + public void saveAdvancedConfiguration() { + getPanel().store(); + } + + @Override + public boolean hasBackgroundJobsRunning() { + // we're single threaded... + return false; + } + + public static void setSkipKnown(boolean flag) { + skipKnown = flag; + } + + public static void setSkipNoExt(boolean flag) { + skipNoExt = flag; + } + +} + diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchOptionsPanelController.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchOptionsPanelController.java new file mode 100644 index 0000000000..f2d31f9055 --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchOptionsPanelController.java @@ -0,0 +1,89 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.fileextmismatch; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import javax.swing.JComponent; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.HelpCtx; +import org.openide.util.Lookup; + +@OptionsPanelController.TopLevelRegistration( + categoryName = "#OptionsCategory_Name_FileExtMismatchOptions", +iconBase = "org/sleuthkit/autopsy/fileextmismatch/options-icon.png", +position = 4, +keywords = "#OptionsCategory_FileExtMismatch", +keywordsCategory = "KeywordSearchOptions") +@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_FileExtMismatchOptions=File Ext Mismatch", "OptionsCategory_FileExtMismatch=File Ext Mismatch"}) +public final class FileExtMismatchOptionsPanelController extends OptionsPanelController { + + private FileExtMismatchConfigPanel panel; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + private boolean changed; + + @Override + public void update() { + getPanel().load(); + changed = false; + } + + @Override + public void applyChanges() { + //getPanel().store(); + getPanel().ok(); + changed = false; + } + + @Override + public void cancel() { + getPanel().cancel(); + } + + @Override + public boolean isValid() { + return getPanel().valid(); + } + + @Override + public boolean isChanged() { + return changed; + } + + @Override + public HelpCtx getHelpCtx() { + return null; // new HelpCtx("...ID") if you have a help set + } + + @Override + public JComponent getComponent(Lookup masterLookup) { + return getPanel(); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener l) { + pcs.addPropertyChangeListener(l); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + pcs.removePropertyChangeListener(l); + } + + private FileExtMismatchConfigPanel getPanel() { + if (panel == null) { + panel = new FileExtMismatchConfigPanel(); + } + return panel; + } + + void changed() { + if (!changed) { + changed = true; + pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); + } + pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + } +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.form b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.form new file mode 100644 index 0000000000..a112c72b72 --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.form @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.java new file mode 100644 index 0000000000..526fef6f9b --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchSimpleConfigPanel.java @@ -0,0 +1,101 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + + +/** + * Instances of this class provide a simplified UI for managing the hash sets configuration. + */ +public class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel { + + public FileExtMismatchSimpleConfigPanel() { + initComponents(); + customizeComponents(); + } + + private void customizeComponents() { + // Hidden for now + skipKnownCheckBox.setVisible(false); + } + + + /** 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + skipKnownCheckBox = new javax.swing.JCheckBox(); + skipNoExtCheckBox = new javax.swing.JCheckBox(); + + skipKnownCheckBox.setSelected(true); + skipKnownCheckBox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSimpleConfigPanel.class, "FileExtMismatchSimpleConfigPanel.skipKnownCheckBox.text")); // NOI18N + skipKnownCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(FileExtMismatchSimpleConfigPanel.class, "FileExtMismatchSimpleConfigPanel.skipKnownCheckBox.toolTipText")); // NOI18N + skipKnownCheckBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + skipKnownCheckBoxActionPerformed(evt); + } + }); + + skipNoExtCheckBox.setSelected(true); + skipNoExtCheckBox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSimpleConfigPanel.class, "FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text")); // NOI18N + skipNoExtCheckBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + skipNoExtCheckBoxActionPerformed(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() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(skipKnownCheckBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(skipNoExtCheckBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(127, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addComponent(skipKnownCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(skipNoExtCheckBox) + .addContainerGap(152, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void skipKnownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownCheckBoxActionPerformed + FileExtMismatchIngestModule.setSkipKnown(skipKnownCheckBox.isSelected()); + }//GEN-LAST:event_skipKnownCheckBoxActionPerformed + + private void skipNoExtCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipNoExtCheckBoxActionPerformed + FileExtMismatchIngestModule.setSkipNoExt(skipNoExtCheckBox.isSelected()); + }//GEN-LAST:event_skipNoExtCheckBoxActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox skipKnownCheckBox; + private javax.swing.JCheckBox skipNoExtCheckBox; + // End of variables declaration//GEN-END:variables +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchXML.java b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchXML.java new file mode 100644 index 0000000000..8de27f4b6f --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/FileExtMismatchXML.java @@ -0,0 +1,184 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 Basis Technology Corp. + * Contact: carrier sleuthkit 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.fileextmismatch; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Level; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.coreutils.XMLUtil; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * Storage of file extension mismatch configuration, which maps mimetypes to + * allowable filename extensions. + */ +public class FileExtMismatchXML { + private static final Logger logger = Logger.getLogger(FileExtMismatchXML.class.getName()); + private static FileExtMismatchXML defaultInstance = null; + + private static final String ENCODING = "UTF-8"; + private static final String XSDFILE = "MismatchConfigSchema.xsd"; + + private static final String ROOT_EL = "mismatch_config"; + private static final String SIG_EL = "signature"; + private static final String EXT_EL = "ext"; + private static final String SIG_MIMETYPE_ATTR = "mimetype"; + + private static final String DEFAULT_CONFIG_FILE_NAME = "mismatch_config.xml"; + + protected String filePath; + + FileExtMismatchXML(String filePath) { + this.filePath = filePath; + + try { + boolean extracted = PlatformUtil.extractResourceToUserConfigDir(FileExtMismatchXML.class, DEFAULT_CONFIG_FILE_NAME); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error copying default mismatch configuration to user dir ", ex); + } + } + + /** + * Singleton provides default configuration from user's directory; user CAN + * modify this file. + */ + public static FileExtMismatchXML getDefault() { + if (defaultInstance == null) { + final String FILTER_CONFIG_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + DEFAULT_CONFIG_FILE_NAME; + defaultInstance = new FileExtMismatchXML(FILTER_CONFIG_FILE); + } + return defaultInstance; + } + + /** + * Load and parse XML + * + * @return Loaded hash map or null on error or null if data does not exist + */ + public HashMap load() { + HashMap sigTypeToExtMap = new HashMap<>(); + + try + { + final Document doc = XMLUtil.loadDoc(FileExtMismatchXML.class, filePath, XSDFILE); + if (doc == null) { + return null; + } + + Element root = doc.getDocumentElement(); + if (root == null) { + logger.log(Level.SEVERE, "Error loading config file: invalid file format (bad root)."); + return null; + } + + NodeList sigNList = root.getElementsByTagName(SIG_EL); + final int numSigs = sigNList.getLength(); + + if (numSigs == 0) { + return null; + } + + for(int sigIndex = 0; sigIndex < numSigs; ++sigIndex) { + Element sigEl = (Element)sigNList.item(sigIndex); + final String mimetype = sigEl.getAttribute(SIG_MIMETYPE_ATTR); + + NodeList extNList = sigEl.getElementsByTagName(EXT_EL); + final int numExts = extNList.getLength(); + + if (numExts != 0) { + List extStrings = new ArrayList<>(); + for(int extIndex = 0; extIndex < numExts; ++extIndex) { + Element extEl = (Element)extNList.item(extIndex); + extStrings.add(extEl.getTextContent()); + } + String[] sarray = (String[])extStrings.toArray(new String[0]); + sigTypeToExtMap.put(mimetype, sarray); + } else { + sigTypeToExtMap.put(mimetype, null); //ok to have an empty type (the ingest module will not use it) + } + } + + } catch (Exception e) { + logger.log(Level.SEVERE, "Error loading config file.", e); + return null; + } + return sigTypeToExtMap; + } + + + /** + * Save XML to filePath, overwriting it if it already exists + * + * @param sigTypeToExtMap String arrays of extensions mapped to each string mimetype. + * @return Loaded hash map or null on error or null if data does not exist + */ + public boolean save(HashMap sigTypeToExtMap) { + boolean success = false; + + DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); + + try { + DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); + Document doc = docBuilder.newDocument(); + + Element rootEl = doc.createElement(ROOT_EL); + doc.appendChild(rootEl); + + Iterator keyIt = sigTypeToExtMap.keySet().iterator(); + + while (keyIt.hasNext()) { + String key = keyIt.next(); + Element sigEl = doc.createElement(SIG_EL); + sigEl.setAttribute(SIG_MIMETYPE_ATTR, key); + + String[] extArray = sigTypeToExtMap.get(key); + if (extArray != null) { + ArrayList extList = new ArrayList<>(Arrays.asList(extArray)); + for (String ext : extList) { + Element extEl = doc.createElement(EXT_EL); + extEl.setTextContent(ext); + sigEl.appendChild(extEl); + } + } + rootEl.appendChild(sigEl); + } + + success = XMLUtil.saveDoc(FileExtMismatchXML.class, filePath, ENCODING, doc); + + } catch (ParserConfigurationException e) { + logger.log(Level.SEVERE, "Error saving keyword list: can't initialize parser.", e); + success = false; + } + return success; + } +} diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/MismatchConfigSchema.xsd b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/MismatchConfigSchema.xsd new file mode 100644 index 0000000000..cf6f271fc0 --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/MismatchConfigSchema.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/mismatch_config.xml b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/mismatch_config.xml new file mode 100644 index 0000000000..7b5c0dbb1c --- /dev/null +++ b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/mismatch_config.xml @@ -0,0 +1,295 @@ + + + + txt + ini + inf + url + reg + cfg + log + lo_ + dat + lst + xml + dtd + xsd + xdr + xsl + xsml + kml + wsdl + box + rdf + manifest + htm + html + shtml + shtm + xhtml + hta + css + js + jsm + vbs + vb + php + php3 + phtml + h + hpp + hxx + cpp + cxx + cc + c + java + cs + asp + aspx + axd + ashx + properties + mak + cmake + la + pl + pm + plx + py + pyw + bat + lua + tex + lsp + lisp + rb + rbw + ps + json + mof + mfl + inc + milk + acro + adm + dun + obe + pro + sam + cmd + rat + htt + iem + policy + pc + catalog + hlp + cnt + sql + rbf + rsp + wpl + dic + aff + iqy + ecf + elm + ent + gdl + gpd + isp + theme + nt + cty + icw + man + ppd + cpx + scp + ver + library-ms + winprf + winprf_backup + svg + + + doc + docx + docm + dotm + dot + dotx + xls + xlt + xla + xlsx + xlsm + xltm + xlam + xlsb + ppt + pot + pps + ppa + pptx + potx + ppam + pptm + potm + ppsm + msi + mst + db + db.keep + wiz + gra + automaticDestinations-ms + customDestinations-ms + feed-ms + + + docx + dotx + xlsx + xlsm + xltm + xlam + xlsb + pptx + potx + ppam + pptm + potm + ppsm + + + doc + dot + + + xls + xlt + xla + + + ppt + pot + pps + ppa + + + zip + docx + dotx + xlsx + xlsm + xltm + xlam + xlsb + pptx + potx + ppam + pptm + potm + ppsm + wmz + jar + amo + xpi + + + odt + + + ods + + + odp + + + pdf + + + rtf + + + htm + html + htx + htmls + hhk + hta + wpl + htt + + + jpg + jpeg + + + tif + tiff + + + png + + + gif + + + bmp + + + bmp + bm + + + ico + + + mp4 + + + mov + qt + mp4 + + + 3gp + + + avi + + + wmv + + + wmv + asf + + + wmv + asf + + + wma + asf + + + mpg + mpeg + + + flv + + + rm + + + rv + + + swf + + \ No newline at end of file diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/options-icon.png b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/options-icon.png new file mode 100644 index 0000000000..e3ca571e32 Binary files /dev/null and b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/options-icon.png differ diff --git a/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/save16.png b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/save16.png new file mode 100644 index 0000000000..1f0caa8346 Binary files /dev/null and b/FileExtMismatch/src/org/sleuthkit/autopsy/fileextmismatch/save16.png differ diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index d9111cbf57..9fc095c4a7 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Wed, 18 Dec 2013 16:55:09 -0500 +#Wed, 15 Jan 2014 15:11:33 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=288 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index ca51680253..eaa57124f0 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Wed, 18 Dec 2013 16:55:09 -0500 +#Wed, 15 Jan 2014 15:11:33 -0500 CTL_MainWindow_Title=Autopsy 3.0.8 CTL_MainWindow_Title_No_Project=Autopsy 3.0.8 diff --git a/nbproject/project.properties b/nbproject/project.properties index aea6502156..27ba384ff4 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -9,6 +9,7 @@ app.version=3.0.8 ### Must be one of: DEVELOPMENT, RELEASE build.type=RELEASE project.org.sleuthkit.autopsy.ewfverify=ewfVerify +project.org.sleuthkit.autopsy.fileextmismatch=FileExtMismatch #build.type=DEVELOPMENT update_versions=false #custom JVM options @@ -34,7 +35,8 @@ modules=\ ${project.org.sleuthkit.autopsy.scalpel}:\ ${project.org.sleuthkit.autopsy.timeline}:\ ${project.org.sleuthkit.autopsy.filetypeid}:\ - ${project.org.sleuthkit.autopsy.ewfverify} + ${project.org.sleuthkit.autopsy.ewfverify}:\ + ${project.org.sleuthkit.autopsy.fileextmismatch} project.org.sleuthkit.autopsy.core=Core project.org.sleuthkit.autopsy.corelibs=CoreLibs project.org.sleuthkit.autopsy.hashdatabase=HashDatabase