mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-08 22:29:33 +00:00
Merge pull request #2076 from BasisOlivers/aut-2034
Serialization for file extension mismatch
This commit is contained in:
commit
cee800dba3
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -18,44 +18,52 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.fileextmismatch;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Do the context menu action for adding a new filename extension to the
|
||||
* mismatch list for the MIME type of the selected node.
|
||||
* extension list for the MIME type.
|
||||
*/
|
||||
class AddFileExtensionAction extends AbstractAction {
|
||||
|
||||
private String extStr;
|
||||
private String mimeTypeStr;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(AddFileExtensionAction.class.getName());
|
||||
private final String extStr;
|
||||
private final String mimeTypeStr;
|
||||
private final FileExtMismatchSettings settings;
|
||||
|
||||
public AddFileExtensionAction(String menuItemStr, String extStr, String mimeTypeStr) {
|
||||
AddFileExtensionAction(String menuItemStr, String extStr, String mimeTypeStr, FileExtMismatchSettings settings) {
|
||||
super(menuItemStr);
|
||||
this.mimeTypeStr = mimeTypeStr;
|
||||
this.extStr = extStr;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Messages({"AddFileExtensionAction.writeError.message=Could not write file extension settings."})
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
HashMap<String, String[]> editableMap = FileExtMismatchXML.getDefault().load();
|
||||
ArrayList<String> editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(mimeTypeStr)));
|
||||
HashMap<String, Set<String>> editableMap;
|
||||
editableMap = settings.getMimeTypeToExtsMap();
|
||||
Set<String> editedExtensions = 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)) {
|
||||
try {
|
||||
FileExtMismatchSettings.writeSettings(new FileExtMismatchSettings(editableMap));
|
||||
} catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
|
||||
//error
|
||||
JOptionPane.showMessageDialog(null,
|
||||
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.msg"),
|
||||
Bundle.AddFileExtensionAction_writeError_message(),
|
||||
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.title"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} // else //in the future we might want to update the statusbar to give feedback to the user
|
||||
logger.log(Level.SEVERE, "Could not write file extension settings.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
OpenIDE-Module-Name=FileExtMismatch
|
||||
OptionsCategory_Name_FileExtMismatchOptions=File Extension Mismatch
|
||||
OptionsCategory_FileExtMismatch=File Extension Mismatch
|
||||
AddFileExtensionAction.msgDlg.msg=Writing XML configuration file failed.
|
||||
AddFileExtensionAction.msgDlg.msg2=File extension mismatch settings could not be read, extensions update not available.
|
||||
AddFileExtensionAction.msgDlg.title=Add Mismatch Extension Error
|
||||
AddFileExtensionAction.extHeaderLbl.text=Allowed Extensions for
|
||||
FileExtMismatchConfigPanel.addExtButton.errLabel.empty=Extension text is empty\!
|
||||
@ -19,7 +19,7 @@ FileExtMismatchConfigPanel.removeExtButton.noneSelected=No extension selected\!
|
||||
FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected=No MIME type selected\!
|
||||
FileExtMismatchConfigPanel.removeExtButton.deleted=Extension {0} deleted.
|
||||
FileExtMismatchConfigPanel.store.msg=Saved.
|
||||
FileExtMismatchConfigPanel.store.msgDlg.msg=Writing XML configuration file failed.
|
||||
FileExtMismatchConfigPanel.store.msgDlg.msg=File extension mismatch settings could not be saved.
|
||||
FileExtMismatchConfigPanel.save.msgDlg.title=Save Error
|
||||
FileExtMismatchConfigPanel.ok.confDlg.msg=Would you like to save configuration changes?
|
||||
FileExtMismatchConfigPanel.confDlg.title=Unsaved Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -19,13 +19,13 @@
|
||||
package org.sleuthkit.autopsy.modules.fileextmismatch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
import org.openide.util.Lookup;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
@ -34,15 +34,14 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
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.
|
||||
* to the extension list for the MIME type of the selected node.
|
||||
*/
|
||||
@ServiceProvider(service = ContextMenuActionsProvider.class)
|
||||
public class FileExtMismatchContextMenuActionsProvider implements ContextMenuActionsProvider {
|
||||
private static final Logger logger = Logger.getLogger(FileExtMismatchContextMenuActionsProvider.class.getName());
|
||||
|
||||
@Override
|
||||
public List<Action> getActions() {
|
||||
@ -63,22 +62,17 @@ public class FileExtMismatchContextMenuActionsProvider implements ContextMenuAct
|
||||
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); //NON-NLS
|
||||
}
|
||||
|
||||
AbstractFile af = Utilities.actionsGlobalContext().lookup(AbstractFile.class);
|
||||
|
||||
if (af != null) {
|
||||
int i = af.getName().lastIndexOf(".");
|
||||
if ((i > -1) && ((i + 1) < af.getName().length())) {
|
||||
extStr = af.getName().substring(i + 1).toLowerCase();
|
||||
}
|
||||
mimeTypeStr = af.getMIMEType();
|
||||
if(mimeTypeStr == null) {
|
||||
mimeTypeStr = "";
|
||||
}
|
||||
int i = af.getName().lastIndexOf(".");
|
||||
if ((i > -1) && ((i + 1) < af.getName().length())) {
|
||||
extStr = af.getName().substring(i + 1).toLowerCase();
|
||||
}
|
||||
mimeTypeStr = af.getMIMEType();
|
||||
if (mimeTypeStr == null) {
|
||||
mimeTypeStr = "";
|
||||
}
|
||||
|
||||
if (!extStr.isEmpty() && !mimeTypeStr.isEmpty()) {
|
||||
// Limit max size so the context window doesn't get ridiculously wide
|
||||
@ -91,16 +85,25 @@ public class FileExtMismatchContextMenuActionsProvider implements ContextMenuAct
|
||||
String menuItemStr = NbBundle.getMessage(this.getClass(),
|
||||
"FileExtMismatchContextMenuActionsProvider.menuItemStr",
|
||||
extStr, mimeTypeStr);
|
||||
actions.add(new AddFileExtensionAction(menuItemStr, extStr, mimeTypeStr));
|
||||
|
||||
// Check if already added
|
||||
HashMap<String, String[]> editableMap = FileExtMismatchXML.getDefault().load();
|
||||
ArrayList<String> 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);
|
||||
HashMap<String, Set<String>> editableMap;
|
||||
try {
|
||||
FileExtMismatchSettings settings = FileExtMismatchSettings.readSettings();
|
||||
editableMap = settings.getMimeTypeToExtsMap();
|
||||
actions.add(new AddFileExtensionAction(menuItemStr, extStr, mimeTypeStr, settings));
|
||||
Set<String> editedExtensions = 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);
|
||||
}
|
||||
} catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.msg2"),
|
||||
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.title"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.log(Level.WARNING, "File extension mismatch settings could not be read, extensions update not available.", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ public class FileExtMismatchDetectorModuleFactory extends IngestModuleFactoryAda
|
||||
assert settings instanceof FileExtMismatchDetectorModuleSettings;
|
||||
if (!(settings instanceof FileExtMismatchDetectorModuleSettings)) {
|
||||
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(),
|
||||
"FileExtMismatchDetectorModuleFactory.createFileIngestModule.exception.msg"));
|
||||
"FileExtMismatchDetectorModuleFactory.getIngestJobSettingsPanel.exception.msg"));
|
||||
}
|
||||
return new FileExtMismatchIngestModule((FileExtMismatchDetectorModuleSettings) settings);
|
||||
}
|
||||
|
@ -18,12 +18,12 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.fileextmismatch;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -31,9 +31,9 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@ -51,7 +51,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
||||
private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName());
|
||||
private final IngestServices services = IngestServices.getInstance();
|
||||
private final FileExtMismatchDetectorModuleSettings settings;
|
||||
private HashMap<String, String[]> SigTypeToExtMap = new HashMap<>();
|
||||
private HashMap<String, Set<String>> mimeTypeToExtsMap = new HashMap<>();
|
||||
private long jobId;
|
||||
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
||||
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||
@ -87,12 +87,16 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Messages({"FileExtMismatchIngestModule.readError.message=Could not read settings."})
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
jobId = context.getJobId();
|
||||
refCounter.incrementAndGet(jobId);
|
||||
|
||||
FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault();
|
||||
SigTypeToExtMap = xmlLoader.load();
|
||||
try {
|
||||
mimeTypeToExtsMap = FileExtMismatchSettings.readSettings().getMimeTypeToExtsMap();
|
||||
} catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
|
||||
throw new IngestModuleException(Bundle.FileExtMismatchIngestModule_readError_message(), ex);
|
||||
}
|
||||
try {
|
||||
this.detector = new FileTypeDetector();
|
||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||
@ -104,7 +108,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
||||
@Override
|
||||
public ProcessResult process(AbstractFile abstractFile) {
|
||||
blackboard = Case.getCurrentCase().getServices().getBlackboard();
|
||||
if(this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
|
||||
if (this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
@ -175,16 +179,12 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
//get known allowed values from the map for this type
|
||||
String[] allowedExtArray = SigTypeToExtMap.get(currActualSigType);
|
||||
if (allowedExtArray != null) {
|
||||
List<String> allowedExtList = Arrays.asList(allowedExtArray);
|
||||
|
||||
Set<String> allowedExtSet = mimeTypeToExtsMap.get(currActualSigType);
|
||||
if (allowedExtSet != null) {
|
||||
// see if the filename ext is in the allowed list
|
||||
if (allowedExtList != null) {
|
||||
for (String e : allowedExtList) {
|
||||
if (e.equals(currActualExt)) {
|
||||
return false;
|
||||
}
|
||||
for (String e : allowedExtSet) {
|
||||
if (e.equals(currActualExt)) {
|
||||
return false;
|
||||
}
|
||||
return true; //potential mismatch
|
||||
}
|
||||
|
@ -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.fileextmismatch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.io.NbObjectInputStream;
|
||||
import org.openide.util.io.NbObjectOutputStream;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Serialization settings for file extension mismatch. Contains static methods
|
||||
* for reading and writing settings, and instances of this class are what is
|
||||
* written to the serialized file.
|
||||
*/
|
||||
class FileExtMismatchSettings implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private HashMap<String, Set<String>> mimeTypeToExtsMap;
|
||||
private static final Logger logger = Logger.getLogger(FileExtMismatchSettings.class.getName());
|
||||
private static final String SIG_EL = "signature"; //NON-NLS
|
||||
private static final String EXT_EL = "ext"; //NON-NLS
|
||||
private static final String SIG_MIMETYPE_ATTR = "mimetype"; //NON-NLS
|
||||
|
||||
private static final String DEFAULT_CONFIG_FILE_NAME = "mismatch_config.xml"; //NON-NLS
|
||||
private static final String FILTER_CONFIG_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + DEFAULT_CONFIG_FILE_NAME;
|
||||
private static final String DEFAULT_SERIALIZED_FILE_NAME = "mismatch_config.settings";
|
||||
private static final String DEFAULT_SERIALIZED_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + DEFAULT_SERIALIZED_FILE_NAME;
|
||||
|
||||
static {
|
||||
try {
|
||||
PlatformUtil.extractResourceToUserConfigDir(FileExtMismatchSettings.class, DEFAULT_CONFIG_FILE_NAME, false);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error copying default mismatch configuration to user dir ", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a settings object based on given mime type map
|
||||
*
|
||||
* @param mimeTypeToExtsMap
|
||||
*/
|
||||
FileExtMismatchSettings(HashMap<String, Set<String>> mimeTypeToExtsMap) {
|
||||
this.mimeTypeToExtsMap = mimeTypeToExtsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mime type to extension map
|
||||
*/
|
||||
HashMap<String, Set<String>> getMimeTypeToExtsMap() {
|
||||
return mimeTypeToExtsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the signature to extension map for this settings.
|
||||
*/
|
||||
void setMimeTypeToExtsMap(HashMap<String, Set<String>> mimeTypeToExtsMap) {
|
||||
this.mimeTypeToExtsMap = mimeTypeToExtsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the file extension mismatch settings.
|
||||
*
|
||||
* @return Loaded settings (empty if there are no settings to load).
|
||||
*/
|
||||
static synchronized FileExtMismatchSettings readSettings() throws FileExtMismatchSettingsException {
|
||||
File serializedFile = new File(DEFAULT_SERIALIZED_FILE_PATH);
|
||||
//Tries reading the serialized file first, as this is the prioritized settings.
|
||||
if (serializedFile.exists()) {
|
||||
return readSerializedSettings();
|
||||
}
|
||||
return readXmlSettings();
|
||||
}
|
||||
|
||||
private static FileExtMismatchSettings readSerializedSettings() throws FileExtMismatchSettingsException {
|
||||
File serializedFile = new File(DEFAULT_SERIALIZED_FILE_PATH);
|
||||
try {
|
||||
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedFile))) {
|
||||
FileExtMismatchSettings fileExtMismatchSettings = (FileExtMismatchSettings) in.readObject();
|
||||
return fileExtMismatchSettings;
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException ex) {
|
||||
throw new FileExtMismatchSettingsException("Couldn't read serialized settings.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static FileExtMismatchSettings readXmlSettings() throws FileExtMismatchSettingsException {
|
||||
HashMap<String, Set<String>> sigTypeToExtMap = new HashMap<>();
|
||||
//Next tries to read the xml file if the serialized file did not exist
|
||||
File xmlFile = new File(FILTER_CONFIG_FILE);
|
||||
if (xmlFile.exists()) {
|
||||
try {
|
||||
final Document doc = XMLUtil.loadDoc(FileExtMismatchSettings.class, FILTER_CONFIG_FILE);
|
||||
if (doc == null) {
|
||||
throw new FileExtMismatchSettingsException("Error loading config file: invalid file format (could not load doc).");
|
||||
}
|
||||
|
||||
Element root = doc.getDocumentElement();
|
||||
if (root == null) {
|
||||
throw new FileExtMismatchSettingsException("Error loading config file: invalid file format (bad root)."); //NON-NLS
|
||||
}
|
||||
|
||||
NodeList sigNList = root.getElementsByTagName(SIG_EL);
|
||||
final int numSigs = sigNList.getLength();
|
||||
|
||||
if (numSigs == 0) {
|
||||
throw new FileExtMismatchSettingsException("Error loading config file: invalid file format (no signature)."); //NON-NLS
|
||||
}
|
||||
|
||||
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) {
|
||||
Set<String> extStrings = new HashSet<>();
|
||||
for (int extIndex = 0; extIndex < numExts; ++extIndex) {
|
||||
Element extEl = (Element) extNList.item(extIndex);
|
||||
extStrings.add(extEl.getTextContent());
|
||||
}
|
||||
sigTypeToExtMap.put(mimetype, extStrings);
|
||||
} else {
|
||||
sigTypeToExtMap.put(mimetype, null); //ok to have an empty type (the ingest module will not use it)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new FileExtMismatchSettingsException("Error loading config file.", e); //NON-NLS
|
||||
}
|
||||
}
|
||||
return new FileExtMismatchSettings(sigTypeToExtMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to disk.
|
||||
*
|
||||
* @param settings The settings to save to disk
|
||||
*
|
||||
* @return Loaded hash map or null on error or null if data does not exist
|
||||
*/
|
||||
static synchronized void writeSettings(FileExtMismatchSettings settings) throws FileExtMismatchSettingsException {
|
||||
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DEFAULT_SERIALIZED_FILE_PATH))) {
|
||||
out.writeObject(settings);
|
||||
} catch (IOException ex) {
|
||||
throw new FileExtMismatchSettingsException(String.format("Failed to write settings to %s", DEFAULT_SERIALIZED_FILE_PATH), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 FileExtMismatchSettingsException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
FileExtMismatchSettingsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
FileExtMismatchSettingsException(String message, Throwable throwable) {
|
||||
super(message, throwable);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -20,19 +20,20 @@ package org.sleuthkit.autopsy.modules.fileextmismatch;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
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.ingest.IngestModuleGlobalSettingsPanel;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||
|
||||
/**
|
||||
@ -42,7 +43,7 @@ import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||
final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FileExtMismatchSettingsPanel.class.getName());
|
||||
private HashMap<String, String[]> editableMap = new HashMap<>();
|
||||
private HashMap<String, Set<String>> editableMap = new HashMap<>();
|
||||
private ArrayList<String> mimeList = null;
|
||||
private ArrayList<String> currentExtensions = null;
|
||||
private MimeTableModel mimeTableModel;
|
||||
@ -382,11 +383,11 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(selectedMime)));
|
||||
Set<String> editedExtensions = 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]));
|
||||
editableMap.put(selectedMime, editedExtensions);
|
||||
|
||||
// Refresh table
|
||||
updateExtList();
|
||||
@ -430,7 +431,7 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
return;
|
||||
}
|
||||
|
||||
editableMap.put(newMime, new String[0]);
|
||||
editableMap.put(newMime, new HashSet<String>());
|
||||
|
||||
// Refresh table
|
||||
updateMimeList();
|
||||
@ -491,12 +492,12 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> editedExtensions = new ArrayList<>(Arrays.asList(editableMap.get(selectedMime)));
|
||||
Set<String> editedExtensions = 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]));
|
||||
editableMap.put(selectedMime, editedExtensions);
|
||||
|
||||
// Refresh tables
|
||||
updateExtList();
|
||||
@ -517,10 +518,10 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
}
|
||||
|
||||
private void updateExtList() {
|
||||
String[] temp = editableMap.get(selectedMime);
|
||||
Set<String> temp = editableMap.get(selectedMime);
|
||||
if (temp != null) {
|
||||
currentExtensions = new ArrayList<>(Arrays.asList(temp));
|
||||
if (temp.length > 0) {
|
||||
currentExtensions = new ArrayList<>(temp);
|
||||
if (temp.size() > 0) {
|
||||
Collections.sort(currentExtensions);
|
||||
}
|
||||
} else {
|
||||
@ -530,14 +531,15 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
|
||||
@Override
|
||||
public void saveSettings() {
|
||||
if (FileExtMismatchXML.getDefault().save(editableMap)) {
|
||||
try {
|
||||
FileExtMismatchSettings.writeSettings(new FileExtMismatchSettings(editableMap));
|
||||
mimeErrLabel.setText(" ");
|
||||
mimeRemoveErrLabel.setText(" ");
|
||||
extRemoveErrLabel.setText(" ");
|
||||
extErrorLabel.setText(" ");
|
||||
|
||||
saveMsgLabel.setText(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.store.msg"));
|
||||
} else {
|
||||
} catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
|
||||
//error
|
||||
JOptionPane.showMessageDialog(this,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
@ -550,9 +552,20 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
||||
|
||||
@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();
|
||||
try {
|
||||
// Load the configuration into a buffer that the user can modify. They can choose
|
||||
// to save it back to the file after making changes.
|
||||
editableMap = FileExtMismatchSettings.readSettings().getMimeTypeToExtsMap();
|
||||
|
||||
} catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
|
||||
//error
|
||||
JOptionPane.showMessageDialog(this,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"AddFileExtensionAction.msgDlg.msg2"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"FileExtMismatchConfigPanel.save.msgDlg.title"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
updateMimeList();
|
||||
updateExtList();
|
||||
}
|
||||
|
@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2014 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.fileextmismatch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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 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.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.
|
||||
*/
|
||||
class FileExtMismatchXML {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FileExtMismatchXML.class.getName());
|
||||
private static FileExtMismatchXML defaultInstance = null;
|
||||
|
||||
private static final String ENCODING = "UTF-8"; //NON-NLS
|
||||
private static final String XSDFILE = "MismatchConfigSchema.xsd"; //NON-NLS
|
||||
|
||||
private static final String ROOT_EL = "mismatch_config"; //NON-NLS
|
||||
private static final String SIG_EL = "signature"; //NON-NLS
|
||||
private static final String EXT_EL = "ext"; //NON-NLS
|
||||
private static final String SIG_MIMETYPE_ATTR = "mimetype"; //NON-NLS
|
||||
|
||||
private static final String DEFAULT_CONFIG_FILE_NAME = "mismatch_config.xml"; //NON-NLS
|
||||
|
||||
protected String filePath;
|
||||
|
||||
FileExtMismatchXML(String filePath) {
|
||||
this.filePath = filePath;
|
||||
|
||||
try {
|
||||
boolean extracted = PlatformUtil.extractResourceToUserConfigDir(FileExtMismatchXML.class, DEFAULT_CONFIG_FILE_NAME, false);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error copying default mismatch configuration to user dir ", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton provides default configuration from user's directory; user CAN
|
||||
* modify this file.
|
||||
*/
|
||||
public static synchronized 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<String, String[]> load() {
|
||||
HashMap<String, String[]> sigTypeToExtMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
final Document doc = XMLUtil.loadDoc(FileExtMismatchXML.class, filePath);
|
||||
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)."); //NON-NLS
|
||||
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<String> extStrings = new ArrayList<>();
|
||||
for (int extIndex = 0; extIndex < numExts; ++extIndex) {
|
||||
Element extEl = (Element) extNList.item(extIndex);
|
||||
extStrings.add(extEl.getTextContent());
|
||||
}
|
||||
String[] sarray = 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); //NON-NLS
|
||||
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<String, String[]> sigTypeToExtMap) {
|
||||
boolean success;
|
||||
|
||||
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
||||
|
||||
try {
|
||||
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
|
||||
Element rootEl = doc.createElement(ROOT_EL);
|
||||
doc.appendChild(rootEl);
|
||||
|
||||
ArrayList<String> mimeTypeList = new ArrayList<>(sigTypeToExtMap.keySet());
|
||||
Collections.sort(mimeTypeList);
|
||||
|
||||
for (String mimeType : mimeTypeList) {
|
||||
Element sigEl = doc.createElement(SIG_EL);
|
||||
sigEl.setAttribute(SIG_MIMETYPE_ATTR, mimeType.toLowerCase());
|
||||
|
||||
String[] extArray = sigTypeToExtMap.get(mimeType);
|
||||
if (extArray != null) {
|
||||
ArrayList<String> extList = new ArrayList<>(Arrays.asList(extArray));
|
||||
Collections.sort(extList);
|
||||
for (String ext : extList) {
|
||||
Element extEl = doc.createElement(EXT_EL);
|
||||
extEl.setTextContent(ext.toLowerCase());
|
||||
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); //NON-NLS
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user