From b277ce16c3dcdcf9aacbb3739ec528dcb58cb579 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Mon, 29 Feb 2016 15:32:11 -0500 Subject: [PATCH 01/29] Began update towards object serialization --- .../modules/hashdatabase/HashDbManager.java | 335 ++++++++++-------- .../HashDbSerializationSettings.java | 40 +++ 2 files changed, 226 insertions(+), 149 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index ada9d6f899..a20104e495 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -38,14 +38,20 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.Serializable; import java.util.concurrent.ExecutionException; import java.util.logging.Level; +import javax.persistence.PersistenceException; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FileUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.util.io.NbObjectInputStream; +import org.openide.util.io.NbObjectOutputStream; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; @@ -72,11 +78,13 @@ public class HashDbManager implements PropertyChangeListener { private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS + private static final String DB_SERIALIZATION_FILE_NAME = "hashDbs.settings"; private static final String XSD_FILE_NAME = "HashsetsSchema.xsd"; //NON-NLS private static final String ENCODING = "UTF-8"; //NON-NLS private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS private static HashDbManager instance = null; private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; + private final String DB_SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + DB_SERIALIZATION_FILE_NAME; private List knownHashSets = new ArrayList<>(); private List knownBadHashSets = new ArrayList<>(); private Set hashSetNames = new HashSet<>(); @@ -109,9 +117,7 @@ public class HashDbManager implements PropertyChangeListener { } private HashDbManager() { - if (hashSetsConfigurationFileExists()) { - readHashSetsConfigurationFromDisk(); - } + readHashSetsConfigurationFromDisk(); } /** @@ -490,9 +496,7 @@ public class HashDbManager implements PropertyChangeListener { hashSetNames.clear(); hashSetPaths.clear(); - if (hashSetsConfigurationFileExists()) { - readHashSetsConfigurationFromDisk(); - } + readHashSetsConfigurationFromDisk(); } private void closeHashDatabases(List hashDatabases) { @@ -507,22 +511,17 @@ public class HashDbManager implements PropertyChangeListener { } private boolean writeHashSetConfigurationToDisk() { - boolean success = false; - DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); - try { - DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); - Document doc = docBuilder.newDocument(); - Element rootEl = doc.createElement(ROOT_ELEMENT); - doc.appendChild(rootEl); - - writeHashDbsToDisk(doc, rootEl, knownHashSets); - writeHashDbsToDisk(doc, rootEl, knownBadHashSets); - - success = XMLUtil.saveDoc(HashDbManager.class, configFilePath, ENCODING, doc); - } catch (ParserConfigurationException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error saving hash databases", ex); //NON-NLS + HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); + try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DB_SERIALIZATION_FILE_PATH))) { + out.writeObject(settings); + File xmlFile = new File(configFilePath); + if (xmlFile.exists()) { + xmlFile.delete(); + } + return true; + } catch (IOException ex) { + throw new PersistenceException(String.format("Failed to write settings to %s", DB_SERIALIZATION_FILE_PATH), ex); } - return success; } private static void writeHashDbsToDisk(Document doc, Element rootEl, List hashDbs) { @@ -559,42 +558,172 @@ public class HashDbManager implements PropertyChangeListener { } private boolean readHashSetsConfigurationFromDisk() { - boolean updatedSchema = false; + if (hashSetsConfigurationFileExists()) { + boolean updatedSchema = false; - // Open the XML document that implements the configuration file. - final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); - if (doc == null) { - return false; - } - - // Get the root element. - Element root = doc.getDocumentElement(); - if (root == null) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS - return false; - } - - // Get the hash set elements. - NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); - int numSets = setsNList.getLength(); - if (numSets == 0) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS - } - - // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of - // a particular hash database is not well-formed. - String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - for (int i = 0; i < numSets; ++i) { - Element setEl = (Element) setsNList.item(i); - - String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); - if (hashSetName.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i); - continue; + // Open the XML document that implements the configuration file. + final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); + if (doc == null) { + return false; } - // Handle configurations saved before duplicate hash set names were not permitted. + // Get the root element. + Element root = doc.getDocumentElement(); + if (root == null) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS + return false; + } + + // Get the hash set elements. + NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); + int numSets = setsNList.getLength(); + if (numSets == 0) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS + } + + // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of + // a particular hash database is not well-formed. + String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + for (int i = 0; i < numSets; ++i) { + Element setEl = (Element) setsNList.item(i); + + String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); + if (hashSetName.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + + // Handle configurations saved before duplicate hash set names were not permitted. + if (hashSetNames.contains(hashSetName)) { + int suffix = 0; + String newHashSetName; + do { + ++suffix; + newHashSetName = hashSetName + suffix; + } while (hashSetNames.contains(newHashSetName)); + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "HashDbManager.replacingDuplicateHashsetNameMsg", + hashSetName, newHashSetName), + NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), + JOptionPane.ERROR_MESSAGE); + hashSetName = newHashSetName; + } + + String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); + if (knownFilesType.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + + // Handle legacy known files types. + if (knownFilesType.equals("NSRL")) { //NON-NLS + knownFilesType = HashDb.KnownFilesType.KNOWN.toString(); + updatedSchema = true; + } + + final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + Boolean seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); + + final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); + + String dbPath; + NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); + if (pathsNList.getLength() > 0) { + Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. + + // Check for legacy path number attribute. + String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); + if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { + updatedSchema = true; + } + + dbPath = pathEl.getTextContent(); + if (dbPath.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); + continue; + } + } else { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); + continue; + } + dbPath = getValidFilePath(hashSetName, dbPath); + + if (null != dbPath) { + try { + addExistingHashDatabaseInternal(hashSetName, dbPath, seearchDuringIngestFlag, sendIngestMessagesFlag, HashDb.KnownFilesType.valueOf(knownFilesType)); + } catch (HashDbManagerException | TskCoreException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "HashDbManager.unableToOpenHashDbMsg", dbPath), + NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), + JOptionPane.ERROR_MESSAGE); + } + } else { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS + } + } + + if (updatedSchema) { + String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS + String messageBoxTitle = NbBundle.getMessage(this.getClass(), + "HashDbManager.msgBoxTitle.confFileFmtChanged"); + String baseMessage = NbBundle.getMessage(this.getClass(), + "HashDbManager.baseMessage.updatedFormatHashDbConfig"); + try { + FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "HashDbManager.savedBackupOfOldConfigMsg", + baseMessage, backupFilePath), + messageBoxTitle, + JOptionPane.INFORMATION_MESSAGE); + } catch (IOException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS + JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); + } + + writeHashSetConfigurationToDisk(); + } + + return true; + } else { + File fileSetFile = new File(DB_SERIALIZATION_FILE_PATH); + if (fileSetFile.exists()) { + try { + try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(DB_SERIALIZATION_FILE_PATH))) { + HashDbSerializationSettings filesSetsSettings = (HashDbSerializationSettings) in.readObject(); + this.setFields(filesSetsSettings); + return true; + } + } catch (IOException | ClassNotFoundException ex) { + throw new PersistenceException(String.format("Failed to read settings from %s", DB_SERIALIZATION_FILE_PATH), ex); + } + } else { + this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); + return true; + } + } + } + + private void setFields(HashDbSerializationSettings settings) throws TskCoreException { + this.knownHashSets = settings.getKnownHashSets(); + this.knownBadHashSets = settings.getKnownBadHashSets(); + this.hashSetNames = new HashSet<>(); + this.hashSetPaths = new HashSet<>(); + for (HashDbManager.HashDb hashDb : knownHashSets) { + String hashSetName = hashDb.getHashSetName(); if (hashSetNames.contains(hashSetName)) { int suffix = 0; String newHashSetName; @@ -602,102 +731,9 @@ public class HashDbManager implements PropertyChangeListener { ++suffix; newHashSetName = hashSetName + suffix; } while (hashSetNames.contains(newHashSetName)); - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.replacingDuplicateHashsetNameMsg", - hashSetName, newHashSetName), - NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), - JOptionPane.ERROR_MESSAGE); - hashSetName = newHashSetName; - } - - String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); - if (knownFilesType.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - - // Handle legacy known files types. - if (knownFilesType.equals("NSRL")) { //NON-NLS - knownFilesType = HashDb.KnownFilesType.KNOWN.toString(); - updatedSchema = true; - } - - final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); - - final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); - - String dbPath; - NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); - if (pathsNList.getLength() > 0) { - Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. - - // Check for legacy path number attribute. - String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); - if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { - updatedSchema = true; - } - - dbPath = pathEl.getTextContent(); - if (dbPath.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - dbPath = getValidFilePath(hashSetName, dbPath); - - if (null != dbPath) { - try { - addExistingHashDatabaseInternal(hashSetName, dbPath, seearchDuringIngestFlag, sendIngestMessagesFlag, HashDb.KnownFilesType.valueOf(knownFilesType)); - } catch (HashDbManagerException | TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.unableToOpenHashDbMsg", dbPath), - NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), - JOptionPane.ERROR_MESSAGE); - } - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS } + this.hashSetPaths.add(hashDb.getDatabasePath()); } - - if (updatedSchema) { - String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS - String messageBoxTitle = NbBundle.getMessage(this.getClass(), - "HashDbManager.msgBoxTitle.confFileFmtChanged"); - String baseMessage = NbBundle.getMessage(this.getClass(), - "HashDbManager.baseMessage.updatedFormatHashDbConfig"); - try { - FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.savedBackupOfOldConfigMsg", - baseMessage, backupFilePath), - messageBoxTitle, - JOptionPane.INFORMATION_MESSAGE); - } catch (IOException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS - JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); - } - - writeHashSetConfigurationToDisk(); - } - - return true; } private String getValidFilePath(String hashSetName, String configuredPath) { @@ -750,7 +786,7 @@ public class HashDbManager implements PropertyChangeListener { * Instances of this class represent hash databases used to classify files * as known or know bad. */ - public static class HashDb { + public static class HashDb implements Serializable { /** * Indicates how files with hashes stored in a particular hash database @@ -778,6 +814,7 @@ public class HashDbManager implements PropertyChangeListener { INDEXING_DONE } + private static final long serialVersionUID = 1L; private int handle; private String hashSetName; private boolean searchDuringIngest; diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java new file mode 100755 index 0000000000..56fb7f2368 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.modules.hashdatabase; + +import java.io.Serializable; +import java.util.List; + +/** + * Class to represent the settings to be serialized for hash databases + */ +class HashDbSerializationSettings implements Serializable { + + private static final long serialVersionUID = 1L; + private final List knownHashSets; + private final List knownBadHashSets; + + /** + * Constructs a settings object to be serialized for hash dbs + * @param knownHashSets + * @param knownBadHashSets + */ + HashDbSerializationSettings(List knownHashSets, List knownBadHashSets) { + this.knownHashSets = knownHashSets; + this.knownBadHashSets = knownBadHashSets; + } + + List getKnownHashSets() { + return this.knownHashSets; + } + + /** + * @return the knownBadHashSets + */ + public List getKnownBadHashSets() { + return knownBadHashSets; + } +} From 9f6f8af5fef90ec52bd05ce2bbca2931f9057559 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 1 Mar 2016 08:37:47 -0500 Subject: [PATCH 02/29] Moving towards serialization of hash dbs --- .../modules/hashdatabase/HashDbManager.java | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index a20104e495..1bc111e448 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -717,22 +717,30 @@ public class HashDbManager implements PropertyChangeListener { } } - private void setFields(HashDbSerializationSettings settings) throws TskCoreException { - this.knownHashSets = settings.getKnownHashSets(); - this.knownBadHashSets = settings.getKnownBadHashSets(); - this.hashSetNames = new HashSet<>(); - this.hashSetPaths = new HashSet<>(); - for (HashDbManager.HashDb hashDb : knownHashSets) { - String hashSetName = hashDb.getHashSetName(); - if (hashSetNames.contains(hashSetName)) { - int suffix = 0; - String newHashSetName; - do { - ++suffix; - newHashSetName = hashSetName + suffix; - } while (hashSetNames.contains(newHashSetName)); + private void setFields(HashDbSerializationSettings settings) { + for (HashDbManager.HashDb hashDb : settings.getKnownHashSets()) { + try { + addExistingHashDatabaseInternal(hashDb.getHashSetName(), hashDb.getDatabasePath(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN); + } catch (HashDbManagerException | TskCoreException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()), + NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), + JOptionPane.ERROR_MESSAGE); + } + } + for (HashDbManager.HashDb hashDb : settings.getKnownBadHashSets()) { + try { + addExistingHashDatabaseInternal(hashDb.getHashSetName(), hashDb.getDatabasePath(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN_BAD); + } catch (HashDbManagerException | TskCoreException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()), + NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), + JOptionPane.ERROR_MESSAGE); } - this.hashSetPaths.add(hashDb.getDatabasePath()); } } From bcc5a21c7dd1731d397623c80335df774b34f932 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 1 Mar 2016 09:16:26 -0500 Subject: [PATCH 03/29] Added db paths to settings so they would be saved properly --- .../modules/hashdatabase/HashDbManager.java | 30 +++++++++++++++---- .../HashDbSerializationSettings.java | 28 ++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 1bc111e448..5d16a6c5e4 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -41,6 +41,8 @@ import java.beans.PropertyChangeSupport; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.Serializable; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.persistence.PersistenceException; @@ -511,15 +513,16 @@ public class HashDbManager implements PropertyChangeListener { } private boolean writeHashSetConfigurationToDisk() { - HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); + try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DB_SERIALIZATION_FILE_PATH))) { + HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); out.writeObject(settings); File xmlFile = new File(configFilePath); if (xmlFile.exists()) { xmlFile.delete(); } return true; - } catch (IOException ex) { + } catch (IOException | TskCoreException ex) { throw new PersistenceException(String.format("Failed to write settings to %s", DB_SERIALIZATION_FILE_PATH), ex); } } @@ -711,16 +714,23 @@ public class HashDbManager implements PropertyChangeListener { throw new PersistenceException(String.format("Failed to read settings from %s", DB_SERIALIZATION_FILE_PATH), ex); } } else { - this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); + try { + this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); + } catch (TskCoreException ex) { + throw new PersistenceException("Failed to create hash database settings", ex); + } + return true; } } } private void setFields(HashDbSerializationSettings settings) { + Map knownPathMap = settings.getKnownPathMap(); + Map knownBadPathMap = settings.getKnownBadPathMap(); for (HashDbManager.HashDb hashDb : settings.getKnownHashSets()) { try { - addExistingHashDatabaseInternal(hashDb.getHashSetName(), hashDb.getDatabasePath(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN); + addExistingHashDatabaseInternal(hashDb.getHashSetName(), knownPathMap.get(hashDb), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN); } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS JOptionPane.showMessageDialog(null, @@ -732,7 +742,7 @@ public class HashDbManager implements PropertyChangeListener { } for (HashDbManager.HashDb hashDb : settings.getKnownBadHashSets()) { try { - addExistingHashDatabaseInternal(hashDb.getHashSetName(), hashDb.getDatabasePath(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN_BAD); + addExistingHashDatabaseInternal(hashDb.getHashSetName(), knownBadPathMap.get(hashDb), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN_BAD); } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS JOptionPane.showMessageDialog(null, @@ -1001,6 +1011,16 @@ public class HashDbManager implements PropertyChangeListener { private void close() throws TskCoreException { SleuthkitJNI.closeHashDatabase(handle); } + + @Override + public int hashCode() { + int code = 23; + code = 47 * code + Integer.hashCode(handle); + code = 47 * code + Objects.hashCode(this.hashSetName); + code = 47 * code + Objects.hashCode(this.propertyChangeSupport); + code = 47 * code + Objects.hashCode(this.knownFilesType); + return code; + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java index 56fb7f2368..f367707c2b 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java @@ -6,7 +6,10 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import java.io.Serializable; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.sleuthkit.datamodel.TskCoreException; /** * Class to represent the settings to be serialized for hash databases @@ -16,15 +19,24 @@ class HashDbSerializationSettings implements Serializable { private static final long serialVersionUID = 1L; private final List knownHashSets; private final List knownBadHashSets; + private final Map knownPathMap = new HashMap<>(); + private final Map knownBadPathMap = new HashMap<>(); /** * Constructs a settings object to be serialized for hash dbs * @param knownHashSets * @param knownBadHashSets */ - HashDbSerializationSettings(List knownHashSets, List knownBadHashSets) { + HashDbSerializationSettings(List knownHashSets, List knownBadHashSets) throws TskCoreException { this.knownHashSets = knownHashSets; this.knownBadHashSets = knownBadHashSets; + for(HashDbManager.HashDb hashDb: this.knownHashSets) { + knownPathMap.put(hashDb, hashDb.getDatabasePath()); + } + + for(HashDbManager.HashDb hashDb: this.knownBadHashSets) { + knownBadPathMap.put(hashDb, hashDb.getDatabasePath()); + } } List getKnownHashSets() { @@ -37,4 +49,18 @@ class HashDbSerializationSettings implements Serializable { public List getKnownBadHashSets() { return knownBadHashSets; } + + /** + * @return the knownPathMap + */ + public Map getKnownPathMap() { + return knownPathMap; + } + + /** + * @return the knownBadPathMap + */ + public Map getKnownBadPathMap() { + return knownBadPathMap; + } } From 182b2d240aa97f04fee6a4e8f76ee2665076acba Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Thu, 10 Mar 2016 15:34:17 -0500 Subject: [PATCH 04/29] Moved towards making serialization follow new protocol --- .../modules/hashdatabase/HashDbManager.java | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 5d16a6c5e4..6cd58e014b 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -136,6 +136,10 @@ public class HashDbManager implements PropertyChangeListener { private HashDbManagerException(String message) { super(message); } + + private HashDbManagerException(String message, Throwable exception) { + super(message, exception); + } } /** @@ -512,18 +516,14 @@ public class HashDbManager implements PropertyChangeListener { hashDatabases.clear(); } - private boolean writeHashSetConfigurationToDisk() { + private boolean writeHashSetConfigurationToDisk() throws HashDbManagerException { try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DB_SERIALIZATION_FILE_PATH))) { HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); out.writeObject(settings); - File xmlFile = new File(configFilePath); - if (xmlFile.exists()) { - xmlFile.delete(); - } return true; } catch (IOException | TskCoreException ex) { - throw new PersistenceException(String.format("Failed to write settings to %s", DB_SERIALIZATION_FILE_PATH), ex); + throw new HashDbManagerException(String.format("Failed to write settings to %s", DB_SERIALIZATION_FILE_PATH), ex); } } @@ -560,8 +560,19 @@ public class HashDbManager implements PropertyChangeListener { return f.exists() && f.canRead() && f.canWrite(); } - private boolean readHashSetsConfigurationFromDisk() { - if (hashSetsConfigurationFileExists()) { + private boolean readHashSetsConfigurationFromDisk() throws HashDbManagerException { + File fileSetFile = new File(DB_SERIALIZATION_FILE_PATH); + if (fileSetFile.exists()) { + try { + try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(DB_SERIALIZATION_FILE_PATH))) { + HashDbSerializationSettings filesSetsSettings = (HashDbSerializationSettings) in.readObject(); + this.setFields(filesSetsSettings); + return true; + } + } catch (IOException | ClassNotFoundException ex) { + throw new PersistenceException(String.format("Failed to read settings from %s", DB_SERIALIZATION_FILE_PATH), ex); + } + } else if (hashSetsConfigurationFileExists()) { boolean updatedSchema = false; // Open the XML document that implements the configuration file. @@ -702,26 +713,13 @@ public class HashDbManager implements PropertyChangeListener { return true; } else { - File fileSetFile = new File(DB_SERIALIZATION_FILE_PATH); - if (fileSetFile.exists()) { - try { - try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(DB_SERIALIZATION_FILE_PATH))) { - HashDbSerializationSettings filesSetsSettings = (HashDbSerializationSettings) in.readObject(); - this.setFields(filesSetsSettings); - return true; - } - } catch (IOException | ClassNotFoundException ex) { - throw new PersistenceException(String.format("Failed to read settings from %s", DB_SERIALIZATION_FILE_PATH), ex); - } - } else { - try { - this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); - } catch (TskCoreException ex) { - throw new PersistenceException("Failed to create hash database settings", ex); - } - - return true; + try { + this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); + } catch (TskCoreException ex) { + throw new PersistenceException("Failed to create hash database settings", ex); } + + return true; } } From 48053dc01f193576c8d1b77f3c7c409f94a3b322 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 18 Mar 2016 10:53:59 -0400 Subject: [PATCH 05/29] Fixed error policy on hash db serialization --- .../modules/hashdatabase/HashDbManager.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 6cd58e014b..b897736d50 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -45,7 +45,6 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import javax.persistence.PersistenceException; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; @@ -516,14 +515,15 @@ public class HashDbManager implements PropertyChangeListener { hashDatabases.clear(); } - private boolean writeHashSetConfigurationToDisk() throws HashDbManagerException { + private boolean writeHashSetConfigurationToDisk() { try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DB_SERIALIZATION_FILE_PATH))) { HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); out.writeObject(settings); return true; } catch (IOException | TskCoreException ex) { - throw new HashDbManagerException(String.format("Failed to write settings to %s", DB_SERIALIZATION_FILE_PATH), ex); + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not wtite hash database settings."); + return false; } } @@ -560,7 +560,7 @@ public class HashDbManager implements PropertyChangeListener { return f.exists() && f.canRead() && f.canWrite(); } - private boolean readHashSetsConfigurationFromDisk() throws HashDbManagerException { + private boolean readHashSetsConfigurationFromDisk() { File fileSetFile = new File(DB_SERIALIZATION_FILE_PATH); if (fileSetFile.exists()) { try { @@ -570,7 +570,8 @@ public class HashDbManager implements PropertyChangeListener { return true; } } catch (IOException | ClassNotFoundException ex) { - throw new PersistenceException(String.format("Failed to read settings from %s", DB_SERIALIZATION_FILE_PATH), ex); + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read hash database settings."); + return false; } } else if (hashSetsConfigurationFileExists()) { boolean updatedSchema = false; @@ -716,7 +717,8 @@ public class HashDbManager implements PropertyChangeListener { try { this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); } catch (TskCoreException ex) { - throw new PersistenceException("Failed to create hash database settings", ex); + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read hash database settings."); + return false; } return true; From 5c67c55db0d836453184319891c4fe917fd85191 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 25 Mar 2016 13:36:37 -0400 Subject: [PATCH 06/29] Begun movement towards new UI --- .../AddFileTypeSignatureDialog.java | 183 +++++++++++++ .../filetypeid/AddFileTypeSignaturePanel.form | 202 ++++++++++++++ .../filetypeid/AddFileTypeSignaturePanel.java | 255 ++++++++++++++++++ .../modules/filetypeid/Bundle.properties | 9 +- .../modules/filetypeid/Bundle_ja.properties | 4 + 5 files changed, 652 insertions(+), 1 deletion(-) create mode 100755 Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java create mode 100755 Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form create mode 100755 Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java new file mode 100755 index 0000000000..10bfe60850 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -0,0 +1,183 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2016 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.modules.filetypeid; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.List; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; +import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog; +import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.Directory; + +/** + * + * A dialog box that allows a user to configure and execute analysis of one or + * more data sources with ingest modules or analysis of the contents of a + * directory with file-level ingest modules. + */ +final class AddFileTypeSignatureDialog extends JDialog { + + private static final long serialVersionUID = 1L; + private final AddFileTypeSignaturePanel addFileTypeSigPanel; + private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text"); + private Signature signature; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + enum BUTTON_PRESSED { + + OK, CANCEL; + } + + /** + * Constructs a dialog box that allows a user to configure and execute + * analysis of the contents of a directory with file-level ingest modules. + * + */ + public AddFileTypeSignatureDialog() { + super(new JFrame(TITLE), TITLE, true); + this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(); + this.display(); + } + + /** + * Displays this dialog. + */ + @Messages({ + "AddFileTypeSignatureDialog.okButton.title=Ok", + "AddFileTypeSignatureDialog.cancelButton.title=Cancel"}) + void display() { + setLayout(new BorderLayout()); + + /** + * Center the dialog. + */ + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + int width = this.getSize().width; + int height = this.getSize().height; + setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2); + + /** + * Get the default or saved ingest job settings for this context and use + * them to create and add an ingest job settings panel. + */ + add(this.addFileTypeSigPanel, BorderLayout.PAGE_START); + + // Add a start ingest button. + JButton okButton = new JButton(Bundle.AddFileTypeSignatureDialog_okButton_title()); + okButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + doButtonAction(true); + } + }); + + // Add a close button. + JButton closeButton = new JButton(Bundle.AddFileTypeSignatureDialog_cancelButton_title()); + closeButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + doButtonAction(false); + } + }); + + // Put the buttons in their own panel, under the settings panel. + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(okButton); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(closeButton); + add(buttonPanel, BorderLayout.LINE_START); + + /** + * Add a handler for when the dialog window is closed directly, + * bypassing the buttons. + */ + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + doButtonAction(false); + } + }); + + /** + * Show the dialog. + */ + pack(); + setResizable(false); + setVisible(true); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener pcl) { + pcs.addPropertyChangeListener(pcl); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener pcl) { + pcs.removePropertyChangeListener(pcl); + } + + /** + * Saves the ingest job settings, optionally starts an ingest job for each + * data source, then closes the dialog + * + * @param okPressed True if ingest job(s) should be started, false + * otherwise. + */ + @Messages({"AddFileTypeSignatureDialog.invalidSignature.message=Invalid signature"}) + private void doButtonAction(boolean okPressed) { + if (okPressed) { + if (this.addFileTypeSigPanel.isValidSignature()) { + Signature oldSignature = this.signature; + this.signature = this.addFileTypeSigPanel.getSignature(); + pcs.firePropertyChange(BUTTON_PRESSED.OK.toString(), oldSignature, signature); + setVisible(false); + clear(); + } else { + JOptionPane.showMessageDialog(this, Bundle.AddFileTypeSignatureDialog_invalidSignature_message()); + } + } else { + Signature oldSignature = this.signature; + this.signature = null; + pcs.firePropertyChange(BUTTON_PRESSED.CANCEL.toString(), oldSignature, signature); + setVisible(false); + clear(); + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form new file mode 100755 index 0000000000..ec7f274f55 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form @@ -0,0 +1,202 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java new file mode 100755 index 0000000000..b1b616759d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -0,0 +1,255 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.modules.filetypeid; + +import java.nio.charset.Charset; +import javax.swing.JOptionPane; +import javax.xml.bind.DatatypeConverter; +import org.openide.util.NbBundle; + +/** + * + * @author oliver + */ +class AddFileTypeSignaturePanel extends javax.swing.JPanel { + + private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem"); + + /** + * Creates new form AddFileTypeSignaturePanel + */ + AddFileTypeSignaturePanel() { + initComponents(); + } + + public Signature getSignature() { + /** + * Get the MIME type. + */ + String typeName = mimeTypeTextField.getText(); + if (typeName.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title"), + JOptionPane.ERROR_MESSAGE); + return null; + } + + /** + * Get the signature type. + */ + FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII; + + /** + * Get the signature bytes. + */ + String sigString = signatureTextField.getText(); + if (sigString.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title"), + JOptionPane.ERROR_MESSAGE); + return null; + } + byte[] signatureBytes; + if (FileType.Signature.Type.RAW == sigType) { + try { + sigString = sigString.replaceAll("\\s", ""); //NON-NLS + signatureBytes = DatatypeConverter.parseHexBinary(sigString); + } catch (IllegalArgumentException ex) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"), + JOptionPane.ERROR_MESSAGE); + return; + } + } else { + signatureBytes = sigString.getBytes(Charset.forName("UTF-8")); + } + + /** + * Get the offset. + */ + long offset; + boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM; + try { + offset = Long.parseUnsignedLong(offsetTextField.getText()); + if(!isRelativeToStart && signatureBytes.length > offset+1) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"), + JOptionPane.ERROR_MESSAGE); + return null; + } + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"), + JOptionPane.ERROR_MESSAGE); + return null; + } + + /** + * Get the interesting files set details. + */ + String filesSetName = ""; + if (postHitCheckBox.isSelected()) { + filesSetName = filesSetNameTextField.getText(); + } + if (postHitCheckBox.isSelected() && filesSetName.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title"), + JOptionPane.ERROR_MESSAGE); + return null; + } + + /** + * Put it all together and reset the file types list component. + */ + FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart); + FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected()); + FileType selected = typesList.getSelectedValue(); + if (selected != null) { + fileTypes.remove(selected); + } + fileTypes.add(fileType); + updateFileTypesListModel(); + typesList.setSelectedValue(fileType, true); + } + /** + * 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() { + + offsetLabel = new javax.swing.JLabel(); + offsetTextField = new javax.swing.JTextField(); + offsetRelativeToComboBox = new javax.swing.JComboBox(); + offsetRelativeToLabel = new javax.swing.JLabel(); + hexPrefixLabel = new javax.swing.JLabel(); + signatureTypeComboBox = new javax.swing.JComboBox(); + signatureLabel = new javax.swing.JLabel(); + signatureTypeLabel = new javax.swing.JLabel(); + signatureTextField = new javax.swing.JTextField(); + + offsetLabel.setFont(offsetLabel.getFont().deriveFont(offsetLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(offsetLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetLabel.text")); // NOI18N + + offsetTextField.setFont(offsetTextField.getFont().deriveFont(offsetTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + offsetTextField.setText(org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetTextField.text")); // NOI18N + + offsetRelativeToComboBox.setFont(offsetRelativeToComboBox.getFont().deriveFont(offsetRelativeToComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + + offsetRelativeToLabel.setFont(offsetRelativeToLabel.getFont().deriveFont(offsetRelativeToLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(offsetRelativeToLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.offsetRelativeToLabel.text")); // NOI18N + + hexPrefixLabel.setFont(hexPrefixLabel.getFont().deriveFont(hexPrefixLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.hexPrefixLabel.text")); // NOI18N + + signatureTypeComboBox.setFont(signatureTypeComboBox.getFont().deriveFont(signatureTypeComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + signatureTypeComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + signatureTypeComboBoxActionPerformed(evt); + } + }); + + signatureLabel.setFont(signatureLabel.getFont().deriveFont(signatureLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureLabel.text")); // NOI18N + + signatureTypeLabel.setFont(signatureTypeLabel.getFont().deriveFont(signatureTypeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(signatureTypeLabel, org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureTypeLabel.text")); // NOI18N + + signatureTextField.setFont(signatureTextField.getFont().deriveFont(signatureTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + signatureTextField.setText(org.openide.util.NbBundle.getMessage(AddFileTypeSignaturePanel.class, "AddFileTypeSignaturePanel.signatureTextField.text")); // NOI18N + signatureTextField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + signatureTextFieldActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(signatureTypeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(hexPrefixLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(offsetRelativeToLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(26, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(signatureTypeLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(hexPrefixLabel) + .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(signatureLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(offsetLabel) + .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(offsetRelativeToLabel)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void signatureTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTypeComboBoxActionPerformed + if (signatureTypeComboBox.getSelectedItem() == RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM) { + hexPrefixLabel.setVisible(true); + signatureTextField.setText("0000"); + } else { + hexPrefixLabel.setVisible(false); + signatureTextField.setText(""); + } + }//GEN-LAST:event_signatureTypeComboBoxActionPerformed + + private void signatureTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTextFieldActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_signatureTextFieldActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel hexPrefixLabel; + private javax.swing.JLabel offsetLabel; + private javax.swing.JComboBox offsetRelativeToComboBox; + private javax.swing.JLabel offsetRelativeToLabel; + private javax.swing.JTextField offsetTextField; + private javax.swing.JLabel signatureLabel; + private javax.swing.JTextField signatureTextField; + private javax.swing.JComboBox signatureTypeComboBox; + private javax.swing.JLabel signatureTypeLabel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties index ccc1bd0aff..b7b02bda24 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties @@ -20,7 +20,7 @@ FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=Signature Type FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text= FileTypeIdGlobalSettingsPanel.signatureLabel.text=Signature FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME Type -FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Save +FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Add FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=Bytes (Hex) FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=String (ASCII) FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=Start @@ -49,3 +49,10 @@ FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to +AddFileTypeSignaturePanel.offsetLabel.text=Byte Offset +AddFileTypeSignaturePanel.signatureTextField.text= +AddFileTypeSignaturePanel.signatureTypeLabel.text=Signature Type +AddFileTypeSignaturePanel.signatureLabel.text=Signature +AddFileTypeSignaturePanel.hexPrefixLabel.text=0x +AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to +AddFileTypeSignaturePanel.offsetTextField.text= diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties index a5f9b02e62..a2860a6408 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties @@ -44,3 +44,7 @@ FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306f\u81ea\u52d5\u7684\u306b FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684 +AddFileTypeSignaturePanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7 +AddFileTypeSignaturePanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3 +AddFileTypeSignaturePanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684 +AddFileTypeSignaturePanel.offsetLabel.text=\u30d0\u30a4\u30c8\u30aa\u30d5\u30bb\u30c3\u30c8 From d2704c879af48d6b9d9055fe4d88782d45dc861b Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 25 Mar 2016 14:28:25 -0400 Subject: [PATCH 07/29] Continued to update ui: --- .../AddFileTypeSignatureDialog.java | 13 +- .../filetypeid/AddFileTypeSignaturePanel.java | 53 +-- .../modules/filetypeid/Bundle.properties | 10 +- .../modules/filetypeid/Bundle_ja.properties | 4 - .../FileTypeIdGlobalSettingsPanel.form | 264 +++++---------- .../FileTypeIdGlobalSettingsPanel.java | 309 ++++-------------- 6 files changed, 167 insertions(+), 486 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index 10bfe60850..ba3cf20ab7 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -33,15 +33,11 @@ import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; -import javax.swing.JOptionPane; import javax.swing.JPanel; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.Directory; /** * @@ -162,21 +158,18 @@ final class AddFileTypeSignatureDialog extends JDialog { @Messages({"AddFileTypeSignatureDialog.invalidSignature.message=Invalid signature"}) private void doButtonAction(boolean okPressed) { if (okPressed) { - if (this.addFileTypeSigPanel.isValidSignature()) { + Signature sig = addFileTypeSigPanel.getSignature(); + if (sig != null) { Signature oldSignature = this.signature; - this.signature = this.addFileTypeSigPanel.getSignature(); + this.signature = sig; pcs.firePropertyChange(BUTTON_PRESSED.OK.toString(), oldSignature, signature); setVisible(false); - clear(); - } else { - JOptionPane.showMessageDialog(this, Bundle.AddFileTypeSignatureDialog_invalidSignature_message()); } } else { Signature oldSignature = this.signature; this.signature = null; pcs.firePropertyChange(BUTTON_PRESSED.CANCEL.toString(), oldSignature, signature); setVisible(false); - clear(); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java index b1b616759d..3959ffb4d8 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -9,6 +9,7 @@ import java.nio.charset.Charset; import javax.swing.JOptionPane; import javax.xml.bind.DatatypeConverter; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; /** * @@ -17,6 +18,8 @@ import org.openide.util.NbBundle; class AddFileTypeSignaturePanel extends javax.swing.JPanel { private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem"); + private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem"); + private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem"); /** * Creates new form AddFileTypeSignaturePanel @@ -24,24 +27,13 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { AddFileTypeSignaturePanel() { initComponents(); } - + public Signature getSignature() { - /** - * Get the MIME type. - */ - String typeName = mimeTypeTextField.getText(); - if (typeName.isEmpty()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title"), - JOptionPane.ERROR_MESSAGE); - return null; - } /** * Get the signature type. */ - FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII; + FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII; /** * Get the signature bytes. @@ -64,7 +56,7 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"), JOptionPane.ERROR_MESSAGE); - return; + return null; } } else { signatureBytes = sigString.getBytes(Charset.forName("UTF-8")); @@ -74,16 +66,16 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { * Get the offset. */ long offset; - boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM; + boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == START_OFFSET_RELATIVE_COMBO_BOX_ITEM; try { - offset = Long.parseUnsignedLong(offsetTextField.getText()); - if(!isRelativeToStart && signatureBytes.length > offset+1) { - JOptionPane.showMessageDialog(null, + offset = Long.parseUnsignedLong(offsetTextField.getText()); + if (!isRelativeToStart && signatureBytes.length > offset + 1) { + JOptionPane.showMessageDialog(null, NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"), JOptionPane.ERROR_MESSAGE); - return null; - } + return null; + } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"), @@ -95,31 +87,14 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { /** * Get the interesting files set details. */ - String filesSetName = ""; - if (postHitCheckBox.isSelected()) { - filesSetName = filesSetNameTextField.getText(); - } - if (postHitCheckBox.isSelected() && filesSetName.isEmpty()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title"), - JOptionPane.ERROR_MESSAGE); - return null; - } /** * Put it all together and reset the file types list component. */ FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart); - FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected()); - FileType selected = typesList.getSelectedValue(); - if (selected != null) { - fileTypes.remove(selected); - } - fileTypes.add(fileType); - updateFileTypesListModel(); - typesList.setSelectedValue(fileType, true); + return signature; } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties index b7b02bda24..edb40dd877 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties @@ -10,15 +10,9 @@ FileTypeIdModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected setting FileTypeIdModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof FileTypeIdModuleSettings FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification. FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL) -FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text=0x FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=Delete -FileTypeIdGlobalSettingsPanel.offsetTextField.text= -FileTypeIdGlobalSettingsPanel.offsetLabel.text=Byte Offset FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=Alert as an "Interesting File" when found -FileTypeIdGlobalSettingsPanel.signatureTextField.text= -FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=Signature Type FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text= -FileTypeIdGlobalSettingsPanel.signatureLabel.text=Signature FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME Type FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Add FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=Bytes (Hex) @@ -48,7 +42,6 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=Custom MIME Types: FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here. FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. -FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetLabel.text=Byte Offset AddFileTypeSignaturePanel.signatureTextField.text= AddFileTypeSignaturePanel.signatureTypeLabel.text=Signature Type @@ -56,3 +49,6 @@ AddFileTypeSignaturePanel.signatureLabel.text=Signature AddFileTypeSignaturePanel.hexPrefixLabel.text=0x AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetTextField.text= +FileTypeIdGlobalSettingsPanel.jButton1.text=Add Signature +FileTypeIdGlobalSettingsPanel.jButton2.text=Edit Signature +FileTypeIdGlobalSettingsPanel.jButton3.text=Delete Signatrue diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties index a2860a6408..863a345b54 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle_ja.properties @@ -24,13 +24,10 @@ FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=\u8aad\u307f\u8fbc\u3 FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title=\u4fdd\u5b58\u304c\u5931\u6557\u3057\u307e\u3057\u305f FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME\u30bf\u30a4\u30d7 FileTypeIdGlobalSettingsPanel.newTypeButton.text=\u65b0\u898f\u30bf\u30a4\u30d7 -FileTypeIdGlobalSettingsPanel.offsetLabel.text=\u30d0\u30a4\u30c8\u30aa\u30d5\u30bb\u30c3\u30c8 FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=\u767a\u898b\u3057\u305f\u969b\u306b\u300c\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u300d\u3068\u8b66\u544a FileTypeIdGlobalSettingsPanel.saveTypeButton.text=\u4fdd\u5b58\u30bf\u30a4\u30d7 FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=\u30b9\u30c8\u30ea\u30f3\u30b0\uff08ASCII\uff09 FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=\u30d0\u30a4\u30c8\uff08HEX\uff09 -FileTypeIdGlobalSettingsPanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3 -FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7 OptionsCategory_Keywords_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID OptionsCategory_Name_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 UserDefinedFileTypesManager.loadFileTypes.errorMessage=\u65e2\u5b58\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f @@ -43,7 +40,6 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME\u30bf\u30a4\u30d7\uff1a FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306f\u81ea\u52d5\u7684\u306b\u591a\u304f\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u691c\u77e5\u3067\u304d\u307e\u3059\u3002\u3053\u3053\u306b\u306f\u3042\u306a\u305f\u306e\u30ab\u30b9\u30bf\u30e0\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684 AddFileTypeSignaturePanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7 AddFileTypeSignaturePanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3 AddFileTypeSignaturePanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684 diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index 7e8b342a16..7dc2df513c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -33,71 +33,48 @@ - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - + @@ -134,29 +111,14 @@ - - - - - - - - - - - - + - - - + + + + - - - - - @@ -165,7 +127,7 @@ - + @@ -232,57 +194,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -328,48 +239,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -448,30 +317,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + - - - + + + - + - - - - - - + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index ee5e9720bf..f95721a1dc 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -59,6 +59,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane */ private DefaultListModel typesListModel; private java.util.List fileTypes; + private AddFileTypeSignatureDialog addSigDialog; /** * This panel implements a property change listener that listens to ingest @@ -110,8 +111,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane DefaultComboBoxModel sigTypeComboBoxModel = new DefaultComboBoxModel<>(); sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); - signatureTypeComboBox.setModel(sigTypeComboBoxModel); - signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); } /** @@ -121,8 +120,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane DefaultComboBoxModel offsetRelComboBoxModel = new DefaultComboBoxModel<>(); offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM); offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM); - offsetRelativeToComboBox.setModel(offsetRelComboBoxModel); - offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM); } /** @@ -168,8 +165,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }; mimeTypeTextField.getDocument().addDocumentListener(listener); - offsetTextField.getDocument().addDocumentListener(listener); - signatureTextField.getDocument().addDocumentListener(listener); filesSetNameTextField.getDocument().addDocumentListener(listener); } @@ -216,8 +211,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane boolean requiredFieldsPopulated = !mimeTypeTextField.getText().isEmpty() - && !offsetTextField.getText().isEmpty() - && !signatureTextField.getText().isEmpty() && (postHitCheckBox.isSelected() ? !filesSetNameTextField.getText().isEmpty() : true); saveTypeButton.setEnabled(!ingestIsRunning && requiredFieldsPopulated); @@ -266,9 +259,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane mimeTypeTextField.setText(fileType.getMimeType()); mimeTypeTextField.setEditable(false); Signature signature = fileType.getSignature(); - FileType.Signature.Type sigType = signature.getType(); - signatureTypeComboBox.setSelectedItem(sigType == FileType.Signature.Type.RAW ? FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); - String signatureBytes; + FileType.Signature.Type sigType = signature.getType();String signatureBytes; if (Signature.Type.RAW == signature.getType()) { signatureBytes = DatatypeConverter.printHexBinary(signature.getSignatureBytes()); } else { @@ -282,9 +273,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane signatureBytes = ""; } } - signatureTextField.setText(signatureBytes); - offsetRelativeToComboBox.setSelectedItem(signature.isRelativeToStart() ? FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM); - offsetTextField.setText(Long.toString(signature.getOffset())); postHitCheckBox.setSelected(fileType.alertOnMatch()); filesSetNameTextField.setEnabled(postHitCheckBox.isSelected()); filesSetNameTextField.setText(fileType.getFilesSetName()); @@ -300,11 +288,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane typesList.clearSelection(); mimeTypeTextField.setText(""); //NON-NLS mimeTypeTextField.setEditable(true); - signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); - hexPrefixLabel.setVisible(true); - signatureTextField.setText("0000"); //NON-NLS - offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM); - offsetTextField.setText(""); //NON-NLS postHitCheckBox.setSelected(false); filesSetNameTextField.setText(""); //NON-NLS filesSetNameTextField.setEnabled(false); @@ -358,24 +341,20 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane separator = new javax.swing.JSeparator(); mimeTypeLabel = new javax.swing.JLabel(); mimeTypeTextField = new javax.swing.JTextField(); - signatureTypeLabel = new javax.swing.JLabel(); - signatureTextField = new javax.swing.JTextField(); - offsetLabel = new javax.swing.JLabel(); - offsetTextField = new javax.swing.JTextField(); newTypeButton = new javax.swing.JButton(); deleteTypeButton = new javax.swing.JButton(); saveTypeButton = new javax.swing.JButton(); - hexPrefixLabel = new javax.swing.JLabel(); - signatureTypeComboBox = new javax.swing.JComboBox(); - signatureLabel = new javax.swing.JLabel(); postHitCheckBox = new javax.swing.JCheckBox(); filesSetNameLabel = new javax.swing.JLabel(); filesSetNameTextField = new javax.swing.JTextField(); ingestRunningWarningLabel = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); - offsetRelativeToComboBox = new javax.swing.JComboBox(); - offsetRelativeToLabel = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jList1 = new javax.swing.JList(); + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); setMaximumSize(new java.awt.Dimension(500, 300)); setPreferredSize(new java.awt.Dimension(500, 300)); @@ -393,23 +372,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane mimeTypeTextField.setFont(mimeTypeTextField.getFont().deriveFont(mimeTypeTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); mimeTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text")); // NOI18N - signatureTypeLabel.setFont(signatureTypeLabel.getFont().deriveFont(signatureTypeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(signatureTypeLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text")); // NOI18N - - signatureTextField.setFont(signatureTextField.getFont().deriveFont(signatureTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - signatureTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureTextField.text")); // NOI18N - signatureTextField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - signatureTextFieldActionPerformed(evt); - } - }); - - offsetLabel.setFont(offsetLabel.getFont().deriveFont(offsetLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(offsetLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetLabel.text")); // NOI18N - - offsetTextField.setFont(offsetTextField.getFont().deriveFont(offsetTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - offsetTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetTextField.text")); // NOI18N - newTypeButton.setFont(newTypeButton.getFont().deriveFont(newTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N newTypeButton.addActionListener(new java.awt.event.ActionListener() { @@ -434,19 +396,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane } }); - hexPrefixLabel.setFont(hexPrefixLabel.getFont().deriveFont(hexPrefixLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text")); // NOI18N - - signatureTypeComboBox.setFont(signatureTypeComboBox.getFont().deriveFont(signatureTypeComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - signatureTypeComboBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - signatureTypeComboBoxActionPerformed(evt); - } - }); - - signatureLabel.setFont(signatureLabel.getFont().deriveFont(signatureLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureLabel.text")); // NOI18N - postHitCheckBox.setFont(postHitCheckBox.getFont().deriveFont(postHitCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(postHitCheckBox, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.postHitCheckBox.text")); // NOI18N postHitCheckBox.addActionListener(new java.awt.event.ActionListener() { @@ -471,10 +420,23 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N - offsetRelativeToComboBox.setFont(offsetRelativeToComboBox.getFont().deriveFont(offsetRelativeToComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + jList1.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + jScrollPane1.setViewportView(jList1); - offsetRelativeToLabel.setFont(offsetRelativeToLabel.getFont().deriveFont(offsetRelativeToLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(offsetRelativeToLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton2.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jButton3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton3.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -488,56 +450,39 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addGap(30, 30, 30)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(deleteTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(newTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(typesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(saveTypeButton) + .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(21, 21, 21) + .addComponent(jLabel2) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(deleteTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(newTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(typesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() .addComponent(filesSetNameLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(postHitCheckBox) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(mimeTypeLabel) - .addGap(30, 30, 30) - .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(postHitCheckBox) - .addGroup(layout.createSequentialGroup() - .addComponent(signatureTypeLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hexPrefixLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(6, 6, 6))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(saveTypeButton) - .addGap(8, 8, 8)) - .addGroup(layout.createSequentialGroup() - .addComponent(offsetRelativeToLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) - .addComponent(jLabel3)) - .addContainerGap(28, Short.MAX_VALUE)))) + .addComponent(jButton1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButton3)) + .addGroup(layout.createSequentialGroup() + .addComponent(mimeTypeLabel) + .addGap(18, 18, 18) + .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE)))))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -565,24 +510,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(mimeTypeLabel) .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(signatureTypeLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(hexPrefixLabel) - .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(signatureLabel)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(offsetLabel) - .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(offsetRelativeToLabel)) - .addGap(16, 16, 16) + .addComponent(jButton1) + .addComponent(jButton2) + .addComponent(jButton3)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(postHitCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -590,7 +524,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(saveTypeButton) - .addGap(0, 21, Short.MAX_VALUE)))) + .addGap(0, 54, Short.MAX_VALUE)))) ); layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton}); @@ -611,99 +545,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }//GEN-LAST:event_deleteTypeButtonActionPerformed private void saveTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTypeButtonActionPerformed - /** - * Get the MIME type. - */ - String typeName = mimeTypeTextField.getText(); - if (typeName.isEmpty()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - /** - * Get the signature type. - */ - FileType.Signature.Type sigType = signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII; - - /** - * Get the signature bytes. - */ - String sigString = signatureTextField.getText(); - if (sigString.isEmpty()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - byte[] signatureBytes; - if (FileType.Signature.Type.RAW == sigType) { - try { - sigString = sigString.replaceAll("\\s", ""); //NON-NLS - signatureBytes = DatatypeConverter.parseHexBinary(sigString); - } catch (IllegalArgumentException ex) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - } else { - signatureBytes = sigString.getBytes(Charset.forName("UTF-8")); - } - - /** - * Get the offset. - */ - long offset; - boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM; - try { - offset = Long.parseUnsignedLong(offsetTextField.getText()); - if(!isRelativeToStart && signatureBytes.length > offset+1) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - } catch (NumberFormatException ex) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - - /** - * Get the interesting files set details. - */ - String filesSetName = ""; - if (postHitCheckBox.isSelected()) { - filesSetName = filesSetNameTextField.getText(); - } - if (postHitCheckBox.isSelected() && filesSetName.isEmpty()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message"), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title"), - JOptionPane.ERROR_MESSAGE); - return; - } - - /** - * Put it all together and reset the file types list component. - */ - FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart); - FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected()); - FileType selected = typesList.getSelectedValue(); - if (selected != null) { - fileTypes.remove(selected); - } - fileTypes.add(fileType); - updateFileTypesListModel(); - typesList.setSelectedValue(fileType, true); }//GEN-LAST:event_saveTypeButtonActionPerformed private void postHitCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postHitCheckBoxActionPerformed @@ -711,42 +553,33 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane enableButtons(); }//GEN-LAST:event_postHitCheckBoxActionPerformed - private void signatureTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTypeComboBoxActionPerformed - if (signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM) { - hexPrefixLabel.setVisible(true); - signatureTextField.setText("0000"); - } else { - hexPrefixLabel.setVisible(false); - signatureTextField.setText(""); - } - }//GEN-LAST:event_signatureTypeComboBoxActionPerformed - - private void signatureTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signatureTextFieldActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_signatureTextFieldActionPerformed + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + this.addSigDialog = new AddFileTypeSignatureDialog(); + addSigDialog.addPropertyChangeListener((PropertyChangeEvent evt1) -> { + if(evt1.getPropertyName().equals(AddFileTypeSignatureDialog.BUTTON_PRESSED.OK.toString())) { + System.out.println("TEST"); + } + }); + }//GEN-LAST:event_jButton1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton deleteTypeButton; private javax.swing.JLabel filesSetNameLabel; private javax.swing.JTextField filesSetNameTextField; - private javax.swing.JLabel hexPrefixLabel; private javax.swing.JLabel ingestRunningWarningLabel; + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JButton jButton3; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; + private javax.swing.JList jList1; + private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel mimeTypeLabel; private javax.swing.JTextField mimeTypeTextField; private javax.swing.JButton newTypeButton; - private javax.swing.JLabel offsetLabel; - private javax.swing.JComboBox offsetRelativeToComboBox; - private javax.swing.JLabel offsetRelativeToLabel; - private javax.swing.JTextField offsetTextField; private javax.swing.JCheckBox postHitCheckBox; private javax.swing.JButton saveTypeButton; private javax.swing.JSeparator separator; - private javax.swing.JLabel signatureLabel; - private javax.swing.JTextField signatureTextField; - private javax.swing.JComboBox signatureTypeComboBox; - private javax.swing.JLabel signatureTypeLabel; private javax.swing.JList typesList; private javax.swing.JScrollPane typesScrollPane; // End of variables declaration//GEN-END:variables From 241e9fc8e9e2b3d0f37033203cdc4ee18d86c58a Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Mon, 28 Mar 2016 14:32:39 -0400 Subject: [PATCH 08/29] Updated UI. --- .../AddFileTypeSignatureDialog.java | 37 +++++----- .../filetypeid/AddFileTypeSignaturePanel.java | 41 +++++++++++- .../modules/filetypeid/Bundle.properties | 6 +- .../FileTypeIdGlobalSettingsPanel.form | 37 +++++----- .../FileTypeIdGlobalSettingsPanel.java | 67 +++++++++++-------- 5 files changed, 114 insertions(+), 74 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index ba3cf20ab7..130791b642 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -51,11 +51,11 @@ final class AddFileTypeSignatureDialog extends JDialog { private final AddFileTypeSignaturePanel addFileTypeSigPanel; private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text"); private Signature signature; - private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + private BUTTON_PRESSED result; enum BUTTON_PRESSED { - OK, CANCEL; + ADD, CANCEL; } /** @@ -63,17 +63,24 @@ final class AddFileTypeSignatureDialog extends JDialog { * analysis of the contents of a directory with file-level ingest modules. * */ - public AddFileTypeSignatureDialog() { + AddFileTypeSignatureDialog() { super(new JFrame(TITLE), TITLE, true); this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(); this.display(); } + /** + * @return the result + */ + public BUTTON_PRESSED getResult() { + return result; + } + /** * Displays this dialog. */ @Messages({ - "AddFileTypeSignatureDialog.okButton.title=Ok", + "AddFileTypeSignatureDialog.addButton.title=Add", "AddFileTypeSignatureDialog.cancelButton.title=Cancel"}) void display() { setLayout(new BorderLayout()); @@ -93,8 +100,8 @@ final class AddFileTypeSignatureDialog extends JDialog { add(this.addFileTypeSigPanel, BorderLayout.PAGE_START); // Add a start ingest button. - JButton okButton = new JButton(Bundle.AddFileTypeSignatureDialog_okButton_title()); - okButton.addActionListener(new ActionListener() { + JButton addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title()); + addButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { doButtonAction(true); @@ -114,7 +121,7 @@ final class AddFileTypeSignatureDialog extends JDialog { JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); - buttonPanel.add(okButton); + buttonPanel.add(addButton); buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); buttonPanel.add(closeButton); add(buttonPanel, BorderLayout.LINE_START); @@ -138,16 +145,6 @@ final class AddFileTypeSignatureDialog extends JDialog { setVisible(true); } - @Override - public void addPropertyChangeListener(PropertyChangeListener pcl) { - pcs.addPropertyChangeListener(pcl); - } - - @Override - public void removePropertyChangeListener(PropertyChangeListener pcl) { - pcs.removePropertyChangeListener(pcl); - } - /** * Saves the ingest job settings, optionally starts an ingest job for each * data source, then closes the dialog @@ -160,15 +157,13 @@ final class AddFileTypeSignatureDialog extends JDialog { if (okPressed) { Signature sig = addFileTypeSigPanel.getSignature(); if (sig != null) { - Signature oldSignature = this.signature; this.signature = sig; - pcs.firePropertyChange(BUTTON_PRESSED.OK.toString(), oldSignature, signature); + this.result = BUTTON_PRESSED.ADD; setVisible(false); } } else { - Signature oldSignature = this.signature; this.signature = null; - pcs.firePropertyChange(BUTTON_PRESSED.CANCEL.toString(), oldSignature, signature); + this.result = BUTTON_PRESSED.CANCEL; setVisible(false); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java index 3959ffb4d8..3b3bd12fd9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -6,9 +6,16 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.nio.charset.Charset; +import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListModel; import javax.swing.JOptionPane; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.xml.bind.DatatypeConverter; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; /** @@ -20,14 +27,47 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem"); private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem"); private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem"); + private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem"); /** * Creates new form AddFileTypeSignaturePanel */ AddFileTypeSignaturePanel() { initComponents(); + customizeComponents(); } + /** + * Does child component initialization in addition to that done by the + * Matisse generated code. + */ + private void customizeComponents() { + setSignatureTypeComboBoxModel(); + setOffsetRealtiveToComboBoxModel(); + } + /** + * Sets the model for the signature type combo box. + */ + private void setSignatureTypeComboBoxModel() { + DefaultComboBoxModel sigTypeComboBoxModel = new DefaultComboBoxModel<>(); + sigTypeComboBoxModel.addElement(RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); + sigTypeComboBoxModel.addElement(ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); + signatureTypeComboBox.setModel(sigTypeComboBoxModel); + signatureTypeComboBox.setSelectedItem(RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); + } + + /** + * Sets the model for the signature type combo box. + */ + private void setOffsetRealtiveToComboBoxModel() { + DefaultComboBoxModel offsetRelComboBoxModel = new DefaultComboBoxModel<>(); + offsetRelComboBoxModel.addElement(START_OFFSET_RELATIVE_COMBO_BOX_ITEM); + offsetRelComboBoxModel.addElement(END_OFFSET_RELATIVE_COMBO_BOX_ITEM); + offsetRelativeToComboBox.setModel(offsetRelComboBoxModel); + offsetRelativeToComboBox.setSelectedItem(START_OFFSET_RELATIVE_COMBO_BOX_ITEM); + } + + public Signature getSignature() { /** @@ -87,7 +127,6 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { /** * Get the interesting files set details. */ - /** * Put it all together and reset the file types list component. */ diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties index edb40dd877..b53027b29d 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties @@ -49,6 +49,6 @@ AddFileTypeSignaturePanel.signatureLabel.text=Signature AddFileTypeSignaturePanel.hexPrefixLabel.text=0x AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetTextField.text= -FileTypeIdGlobalSettingsPanel.jButton1.text=Add Signature -FileTypeIdGlobalSettingsPanel.jButton2.text=Edit Signature -FileTypeIdGlobalSettingsPanel.jButton3.text=Delete Signatrue +FileTypeIdGlobalSettingsPanel.addSigButton.text=Add Signature +FileTypeIdGlobalSettingsPanel.editSigButton.text=Edit Signature +FileTypeIdGlobalSettingsPanel.deleteSigButton.text=Delete Signatrue diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index 7dc2df513c..b30ead2299 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -59,11 +59,11 @@ - + - + - + @@ -114,9 +114,9 @@ - - - + + + @@ -326,40 +326,35 @@ - - - - - - - - + + - + - + - + + - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index f95721a1dc..1b551412fc 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -36,6 +36,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; +import org.sleuthkit.autopsy.modules.filetypeid.AddFileTypeSignatureDialog.BUTTON_PRESSED; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; import org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException; @@ -87,7 +88,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane */ @NbBundle.Messages({"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"}) private void customizeComponents() { - setName(Bundle.FileTypeIdGlobalSettingsPanel_Title()); + setName(Bundle.FileTypeIdGlobalSettingsPanel_Title()); setFileTypesListModel(); setSignatureTypeComboBoxModel(); setOffsetRealtiveToComboBoxModel(); @@ -112,7 +113,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM); } - + /** * Sets the model for the signature type combo box. */ @@ -259,7 +260,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane mimeTypeTextField.setText(fileType.getMimeType()); mimeTypeTextField.setEditable(false); Signature signature = fileType.getSignature(); - FileType.Signature.Type sigType = signature.getType();String signatureBytes; + FileType.Signature.Type sigType = signature.getType(); + String signatureBytes; if (Signature.Type.RAW == signature.getType()) { signatureBytes = DatatypeConverter.printHexBinary(signature.getSignatureBytes()); } else { @@ -352,9 +354,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jLabel3 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); jList1 = new javax.swing.JList(); - jButton1 = new javax.swing.JButton(); - jButton2 = new javax.swing.JButton(); - jButton3 = new javax.swing.JButton(); + addSigButton = new javax.swing.JButton(); + editSigButton = new javax.swing.JButton(); + deleteSigButton = new javax.swing.JButton(); setMaximumSize(new java.awt.Dimension(500, 300)); setPreferredSize(new java.awt.Dimension(500, 300)); @@ -421,22 +423,27 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N jList1.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + String[] strings = {}; public int getSize() { return strings.length; } public Object getElementAt(int i) { return strings[i]; } }); jScrollPane1.setViewportView(jList1); - org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton1.text")); // NOI18N - jButton1.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(addSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.addSigButton.text")); // NOI18N + addSigButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + addButtonMousePressed(evt); + } + }); + addSigButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - jButton1ActionPerformed(evt); + addSigButtonActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton2.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(editSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.editSigButton.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jButton3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jButton3.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteSigButton.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -473,11 +480,11 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(postHitCheckBox) .addGroup(layout.createSequentialGroup() - .addComponent(jButton1) + .addComponent(addSigButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jButton2) + .addComponent(editSigButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jButton3)) + .addComponent(deleteSigButton)) .addGroup(layout.createSequentialGroup() .addComponent(mimeTypeLabel) .addGap(18, 18, 18) @@ -513,9 +520,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jButton1) - .addComponent(jButton2) - .addComponent(jButton3)) + .addComponent(addSigButton) + .addComponent(editSigButton) + .addComponent(deleteSigButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(postHitCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -553,23 +560,27 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane enableButtons(); }//GEN-LAST:event_postHitCheckBoxActionPerformed - private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - this.addSigDialog = new AddFileTypeSignatureDialog(); - addSigDialog.addPropertyChangeListener((PropertyChangeEvent evt1) -> { - if(evt1.getPropertyName().equals(AddFileTypeSignatureDialog.BUTTON_PRESSED.OK.toString())) { - System.out.println("TEST"); + private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed + + }//GEN-LAST:event_addSigButtonActionPerformed + + private void addButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMousePressed + if (evt.getSource().equals(this.addSigButton)) { + this.addSigDialog = new AddFileTypeSignatureDialog(); + if(addSigDialog.getResult() == BUTTON_PRESSED.ADD) { + System.out.println("Gottem"); } - }); - }//GEN-LAST:event_jButton1ActionPerformed + } + }//GEN-LAST:event_addButtonMousePressed // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addSigButton; + private javax.swing.JButton deleteSigButton; private javax.swing.JButton deleteTypeButton; + private javax.swing.JButton editSigButton; private javax.swing.JLabel filesSetNameLabel; private javax.swing.JTextField filesSetNameTextField; private javax.swing.JLabel ingestRunningWarningLabel; - private javax.swing.JButton jButton1; - private javax.swing.JButton jButton2; - private javax.swing.JButton jButton3; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JList jList1; From f1551764b500d10674419a7329d80938ac724b07 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Mon, 28 Mar 2016 16:03:04 -0400 Subject: [PATCH 09/29] Moved towards Signature list --- .../autopsy/modules/filetypeid/FileType.java | 150 ++++++++++-------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 4f7f0bd043..6b9e57c79c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; @@ -27,31 +29,31 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** - * Represents a file type characterized by a file signature. + * Represents a file type characterized by a file signatures. *

* Thread-safe (immutable). */ class FileType { private final String mimeType; - private final Signature signature; + private final List signatures; private final String interestingFilesSetName; private final boolean alert; /** * Creates a representation of a file type characterized by a file - * signature. + * signatures. * * @param mimeType The mime type to associate with this file type. - * @param signature The signature that characterizes this file type. + * @param signature The signatures that characterizes this file type. * @param filesSetName The name of an interesting files set that includes * files of this type, may be the empty string. * @param alert Whether the user wishes to be alerted when a file * matching this type is encountered. */ - FileType(String mimeType, final Signature signature, String filesSetName, boolean alert) { + FileType(String mimeType, List signatures, String filesSetName, boolean alert) { this.mimeType = mimeType; - this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart()); + this.signatures = signatures; this.interestingFilesSetName = filesSetName; this.alert = alert; } @@ -66,12 +68,12 @@ class FileType { } /** - * Gets the signature associated with this file type. + * Gets the signatures associated with this file type. * - * @return The signature. + * @return The signatures. */ - Signature getSignature() { - return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart()); + List getSignatures() { + return Collections.unmodifiableList(this.signatures); } /** @@ -82,7 +84,12 @@ class FileType { * @return True or false. */ boolean matches(final AbstractFile file) { - return signature.containedIn(file); + for (Signature sig : this.signatures) { + if (!sig.containedIn(file)) { + return false; + } + } + return true; } /** @@ -104,19 +111,20 @@ class FileType { String getFilesSetName() { return interestingFilesSetName; } - + @Override public String toString() { return this.mimeType; } - + @Override public boolean equals(Object other) { - if(other != null && other instanceof FileType) { + if (other != null && other instanceof FileType) { FileType that = (FileType) other; - if(this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature())) + if (this.getMimeType().equals(that.getMimeType()) && this.getSignatures().equals(that.getSignatures())) { return true; - } + } + } return false; } @@ -124,12 +132,12 @@ class FileType { public int hashCode() { int hash = 7; hash = 67 * hash + Objects.hashCode(this.mimeType); - hash = 67 * hash + Objects.hashCode(this.signature); + hash = 67 * hash + Objects.hashCode(this.signatures); return hash; } /** - * A file signature consisting of a sequence of bytes at a specific offset + * A file signatures consisting of a sequence of bytes at a specific offset * within a file. *

* Thread-safe (immutable). @@ -139,9 +147,10 @@ class FileType { private static final Logger logger = Logger.getLogger(Signature.class.getName()); /** - * The way the signature byte sequence should be interpreted. + * The way the signatures byte sequence should be interpreted. */ enum Type { + RAW, ASCII }; @@ -151,13 +160,13 @@ class FileType { private final boolean isRelativeToStart; /** - * Creates a file signature consisting of a sequence of bytes at a + * Creates a file signatures consisting of a sequence of bytes at a * specific offset within a file. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. - * @param type The type of data in the byte array. Impacts - * how it is displayed to the user in the UI. + * @param signatureBytes The signatures bytes. + * @param offset The offset of the signatures bytes. + * @param type The type of data in the byte array. Impacts how + * it is displayed to the user in the UI. */ Signature(final byte[] signatureBytes, long offset, Type type) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -165,13 +174,13 @@ class FileType { this.type = type; this.isRelativeToStart = true; } - + /** - * Creates a file signature consisting of an ASCII string at a - * specific offset within a file. + * Creates a file signatures consisting of an ASCII string at a specific + * offset within a file. * * @param signatureString The ASCII string - * @param offset The offset of the signature bytes. + * @param offset The offset of the signatures bytes. */ Signature(String signatureString, long offset) { this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); @@ -179,15 +188,15 @@ class FileType { this.type = Type.ASCII; this.isRelativeToStart = true; } - + /** - * Creates a file signature consisting of a sequence of bytes at a - * specific offset within a file. If bytes correspond to an ASCII - * string, use one of the other constructors so that the string is - * displayed to the user instead of the raw bytes. + * Creates a file signatures consisting of a sequence of bytes at a + * specific offset within a file. If bytes correspond to an ASCII + * string, use one of the other constructors so that the string is + * displayed to the user instead of the raw bytes. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. + * @param signatureBytes The signatures bytes. + * @param offset The offset of the signatures bytes. */ Signature(final byte[] signatureBytes, long offset) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -195,16 +204,17 @@ class FileType { this.type = Type.RAW; this.isRelativeToStart = true; } - + /** - * Creates a file signature consisting of a sequence of bytes at a + * Creates a file signatures consisting of a sequence of bytes at a * specific offset within a file. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. - * @param type The type of data in the byte array. Impacts - * how it is displayed to the user in the UI. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureBytes The signatures bytes. + * @param offset The offset of the signatures bytes. + * @param type The type of data in the byte array. Impacts + * how it is displayed to the user in the UI. + * @param isRelativeToStart Determines whether this signatures is + * relative to start. */ Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -212,14 +222,15 @@ class FileType { this.type = type; this.isRelativeToStart = isRelativeToStart; } - + /** - * Creates a file signature consisting of an ASCII string at a - * specific offset within a file. + * Creates a file signatures consisting of an ASCII string at a specific + * offset within a file. * - * @param signatureString The ASCII string - * @param offset The offset of the signature bytes. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureString The ASCII string + * @param offset The offset of the signatures bytes. + * @param isRelativeToStart Determines whether this signatures is + * relative to start. */ Signature(String signatureString, long offset, boolean isRelativeToStart) { this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); @@ -227,16 +238,17 @@ class FileType { this.type = Type.ASCII; this.isRelativeToStart = isRelativeToStart; } - + /** - * Creates a file signature consisting of a sequence of bytes at a - * specific offset within a file. If bytes correspond to an ASCII - * string, use one of the other constructors so that the string is - * displayed to the user instead of the raw bytes. + * Creates a file signatures consisting of a sequence of bytes at a + * specific offset within a file. If bytes correspond to an ASCII + * string, use one of the other constructors so that the string is + * displayed to the user instead of the raw bytes. * - * @param signatureBytes The signature bytes. - * @param offset The offset of the signature bytes. - * @param isRelativeToStart Determines whether this signature is relative to start. + * @param signatureBytes The signatures bytes. + * @param offset The offset of the signatures bytes. + * @param isRelativeToStart Determines whether this signatures is + * relative to start. */ Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) { this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); @@ -246,7 +258,7 @@ class FileType { } /** - * Gets the byte sequence of the signature. + * Gets the byte sequence of the signatures. * * @return The byte sequence as an array of bytes. */ @@ -255,7 +267,7 @@ class FileType { } /** - * Gets the offset of the signature. + * Gets the offset of the signatures. * * @return The offset. */ @@ -264,20 +276,20 @@ class FileType { } /** - * Gets the interpretation of the byte sequence for the signature. + * Gets the interpretation of the byte sequence for the signatures. * - * @return The signature type. + * @return The signatures type. */ Type getType() { return type; } - + boolean isRelativeToStart() { return isRelativeToStart; } /** - * Determines whether or not the signature is contained within a given + * Determines whether or not the signatures is contained within a given * file. * * @param file The file to test @@ -285,14 +297,15 @@ class FileType { * @return True or false. */ boolean containedIn(final AbstractFile file) { - if(offset >= file.getSize()) { + if (offset >= file.getSize()) { return false; // File is too small, offset lies outside file. } long actualOffset = offset; - if(!isRelativeToStart) + if (!isRelativeToStart) { actualOffset = file.getSize() - 1 - offset; + } if (file.getSize() < (actualOffset + signatureBytes.length)) { - return false; /// too small, can't contain this signature + return false; /// too small, can't contain this signatures } try { byte[] buffer = new byte[signatureBytes.length]; @@ -308,15 +321,16 @@ class FileType { return false; } } - + @Override public boolean equals(Object other) { if (other != null && other instanceof Signature) { Signature that = (Signature) other; - if(Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes()) + if (Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes()) && this.getOffset() == that.getOffset() - && this.getType().equals(that.getType())) + && this.getType().equals(that.getType())) { return true; + } } return false; } From 7cc2e221f3154ec20d0a82ea7635a0a661007bcf Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 29 Mar 2016 11:45:31 -0400 Subject: [PATCH 10/29] Made signatures show in ui. --- .../AddFileTypeSignatureDialog.java | 7 +++ .../autopsy/modules/filetypeid/FileType.java | 9 ++- .../FileTypeIdGlobalSettingsPanel.form | 7 ++- .../FileTypeIdGlobalSettingsPanel.java | 49 ++++++++-------- .../UserDefinedFileTypesManager.java | 57 ++++++++++++++----- 5 files changed, 84 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index 130791b642..75a162c4da 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -53,6 +53,13 @@ final class AddFileTypeSignatureDialog extends JDialog { private Signature signature; private BUTTON_PRESSED result; + /** + * @return the signature + */ + public Signature getSignature() { + return signature; + } + enum BUTTON_PRESSED { ADD, CANCEL; diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 6afba5cab1..4e6707e1ef 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.io.Serializable; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -55,7 +56,7 @@ class FileType implements Serializable { */ FileType(String mimeType, List signatures, String filesSetName, boolean alert) { this.mimeType = mimeType; - this.signatures = signatures; + this.signatures = new ArrayList<>(signatures); this.interestingFilesSetName = filesSetName; this.alert = alert; } @@ -75,7 +76,11 @@ class FileType implements Serializable { * @return The signatures. */ List getSignatures() { - return Collections.unmodifiableList(this.signatures); + return this.signatures; + } + + void addSignature(Signature sig) { + this.signatures.add(sig); } /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index b30ead2299..e74b45d13f 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -324,12 +324,15 @@ - + - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 1b551412fc..7b67b55755 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -22,11 +22,12 @@ import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; import java.util.Collections; +import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; +import javax.swing.ListModel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -61,6 +62,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private DefaultListModel typesListModel; private java.util.List fileTypes; private AddFileTypeSignatureDialog addSigDialog; + private DefaultListModel signaturesListModel; /** * This panel implements a property change listener that listens to ingest @@ -90,6 +92,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private void customizeComponents() { setName(Bundle.FileTypeIdGlobalSettingsPanel_Title()); setFileTypesListModel(); + setSignaturesListModel(); setSignatureTypeComboBoxModel(); setOffsetRealtiveToComboBoxModel(); clearTypeDetailsComponents(); @@ -104,6 +107,11 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane typesListModel = new DefaultListModel<>(); typesList.setModel(typesListModel); } + + private void setSignaturesListModel() { + this.signaturesListModel = new DefaultListModel<>(); + signatureList.setModel(signaturesListModel); + } /** * Sets the model for the signature type combo box. @@ -259,21 +267,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane if (null != fileType) { mimeTypeTextField.setText(fileType.getMimeType()); mimeTypeTextField.setEditable(false); - Signature signature = fileType.getSignature(); - FileType.Signature.Type sigType = signature.getType(); - String signatureBytes; - if (Signature.Type.RAW == signature.getType()) { - signatureBytes = DatatypeConverter.printHexBinary(signature.getSignatureBytes()); - } else { - try { - signatureBytes = new String(signature.getSignatureBytes(), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - JOptionPane.showMessageDialog(null, - ex.getLocalizedMessage(), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"), - JOptionPane.ERROR_MESSAGE); - signatureBytes = ""; - } + List signatures = fileType.getSignatures(); + this.signaturesListModel.clear(); + for(Signature sig: signatures) { + signaturesListModel.addElement(sig); } postHitCheckBox.setSelected(fileType.alertOnMatch()); filesSetNameTextField.setEnabled(postHitCheckBox.isSelected()); @@ -353,7 +350,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); - jList1 = new javax.swing.JList(); + signatureList = new javax.swing.JList(); addSigButton = new javax.swing.JButton(); editSigButton = new javax.swing.JButton(); deleteSigButton = new javax.swing.JButton(); @@ -422,12 +419,12 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N - jList1.setModel(new javax.swing.AbstractListModel() { - String[] strings = {}; - public int getSize() { return strings.length; } - public Object getElementAt(int i) { return strings[i]; } + signatureList.setModel(new javax.swing.AbstractListModel() { + Signature[] signatures = {}; + public int getSize() { return signatures.length; } + public Signature getElementAt(int i) { return signatures[i]; } }); - jScrollPane1.setViewportView(jList1); + jScrollPane1.setViewportView(signatureList); org.openide.awt.Mnemonics.setLocalizedText(addSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.addSigButton.text")); // NOI18N addSigButton.addMouseListener(new java.awt.event.MouseAdapter() { @@ -561,14 +558,14 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }//GEN-LAST:event_postHitCheckBoxActionPerformed private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed - + }//GEN-LAST:event_addSigButtonActionPerformed private void addButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMousePressed if (evt.getSource().equals(this.addSigButton)) { this.addSigDialog = new AddFileTypeSignatureDialog(); - if(addSigDialog.getResult() == BUTTON_PRESSED.ADD) { - System.out.println("Gottem"); + if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { + signaturesListModel.addElement(this.addSigDialog.getSignature()); } } }//GEN-LAST:event_addButtonMousePressed @@ -583,7 +580,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private javax.swing.JLabel ingestRunningWarningLabel; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; - private javax.swing.JList jList1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel mimeTypeLabel; private javax.swing.JTextField mimeTypeTextField; @@ -591,6 +587,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private javax.swing.JCheckBox postHitCheckBox; private javax.swing.JButton saveTypeButton; private javax.swing.JSeparator separator; + private javax.swing.JList signatureList; private javax.swing.JList typesList; private javax.swing.JScrollPane typesScrollPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index 125293e2f9..de6959ef26 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -27,6 +27,7 @@ import java.io.UnsupportedEncodingException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.logging.Level; import javax.persistence.PersistenceException; @@ -188,55 +189,79 @@ final class UserDefinedFileTypesManager { FileType fileType; try { - // Add rule for xml - fileType = new FileType("text/xml", new Signature(" signatureList; + signatureList = new ArrayList<>(); + signatureList.add(new Signature("(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for gzip - byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS - fileType = new FileType("application/x-gzip", new Signature(byteArray, 0L), "", false); //NON-NLS + byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 0L)); + fileType = new FileType("application/x-gzip", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .wk1 byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS - fileType = new FileType("application/x-123", new Signature(byteArray, 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 0L)); + fileType = new FileType("application/x-123", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for Radiance image byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS - fileType = new FileType("image/vnd.radiance", new Signature(byteArray, 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 0L)); + fileType = new FileType("image/vnd.radiance", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .dcx image byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS - fileType = new FileType("image/x-dcx", new Signature(byteArray, 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 0L)); + fileType = new FileType("image/x-dcx", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .ics image - fileType = new FileType("image/x-icns", new Signature("icns", 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature("icns", 0L)); + fileType = new FileType("image/x-icns", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pict image byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS - fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 522L)); + fileType = new FileType("image/x-pict", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); byteArray = DatatypeConverter.parseHexBinary("1100"); //NON-NLS - fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 522L)); + fileType = new FileType("image/x-pict", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pam - fileType = new FileType("image/x-portable-arbitrarymap", new Signature("P7", 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature("P7", 0L)); + fileType = new FileType("image/x-portable-arbitrarymap", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pfm - fileType = new FileType("image/x-portable-floatmap", new Signature("PF", 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature("PF", 0L)); + fileType = new FileType("image/x-portable-floatmap", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); - fileType = new FileType("image/x-portable-floatmap", new Signature("Pf", 0L), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature("Pf", 0L)); + fileType = new FileType("image/x-portable-floatmap", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .tga byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS - fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS + signatureList = new ArrayList<>(); + signatureList.add(new Signature(byteArray, 17, false)); + fileType = new FileType("image/x-tga", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); } // parseHexBinary() throws this if the argument passed in is not Hex catch (IllegalArgumentException e) { @@ -409,7 +434,9 @@ final class UserDefinedFileTypesManager { Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem); String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem); boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem); - return new FileType(mimeType, signature, filesSetName, alert); + List sigList = new ArrayList<>(); + sigList.add(signature); + return new FileType(mimeType, sigList, filesSetName, alert); } /** From 03a5ce78f2d5097e3bb98ac591d6f619b14c628d Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 29 Mar 2016 12:11:32 -0400 Subject: [PATCH 11/29] Added toString to file type signature. --- .../autopsy/modules/filetypeid/FileType.java | 80 ++++++++----------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 4e6707e1ef..7f2aa7d6f9 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -19,13 +19,16 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.logging.Level; +import javax.swing.JOptionPane; +import javax.xml.bind.DatatypeConverter; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; @@ -78,7 +81,7 @@ class FileType implements Serializable { List getSignatures() { return this.signatures; } - + void addSignature(Signature sig) { this.signatures.add(sig); } @@ -150,7 +153,7 @@ class FileType implements Serializable { * Thread-safe (immutable). */ static class Signature implements Serializable { - + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(Signature.class.getName()); @@ -171,13 +174,8 @@ class FileType implements Serializable { * Creates a file signatures consisting of a sequence of bytes at a * specific offset within a file. * -<<<<<<< HEAD - * @param signatureBytes The signatures bytes. - * @param offset The offset of the signatures bytes. -======= * @param signatureBytes The signature bytes. * @param offset The offset of the signature bytes. ->>>>>>> upstream/develop * @param type The type of data in the byte array. Impacts how * it is displayed to the user in the UI. */ @@ -189,19 +187,11 @@ class FileType implements Serializable { } /** -<<<<<<< HEAD - * Creates a file signatures consisting of an ASCII string at a specific - * offset within a file. - * - * @param signatureString The ASCII string - * @param offset The offset of the signatures bytes. -======= * Creates a file signature consisting of an ASCII string at a specific * offset within a file. * * @param signatureString The ASCII string * @param offset The offset of the signature bytes. ->>>>>>> upstream/develop */ Signature(String signatureString, long offset) { this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); @@ -211,11 +201,7 @@ class FileType implements Serializable { } /** -<<<<<<< HEAD - * Creates a file signatures consisting of a sequence of bytes at a -======= * Creates a file signature consisting of a sequence of bytes at a ->>>>>>> upstream/develop * specific offset within a file. If bytes correspond to an ASCII * string, use one of the other constructors so that the string is * displayed to the user instead of the raw bytes. @@ -234,19 +220,11 @@ class FileType implements Serializable { * Creates a file signatures consisting of a sequence of bytes at a * specific offset within a file. * -<<<<<<< HEAD - * @param signatureBytes The signatures bytes. - * @param offset The offset of the signatures bytes. - * @param type The type of data in the byte array. Impacts - * how it is displayed to the user in the UI. - * @param isRelativeToStart Determines whether this signatures is -======= * @param signatureBytes The signature bytes. * @param offset The offset of the signature bytes. * @param type The type of data in the byte array. Impacts * how it is displayed to the user in the UI. * @param isRelativeToStart Determines whether this signature is ->>>>>>> upstream/develop * relative to start. */ Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) { @@ -257,21 +235,12 @@ class FileType implements Serializable { } /** -<<<<<<< HEAD - * Creates a file signatures consisting of an ASCII string at a specific - * offset within a file. - * - * @param signatureString The ASCII string - * @param offset The offset of the signatures bytes. - * @param isRelativeToStart Determines whether this signatures is -======= * Creates a file signature consisting of an ASCII string at a specific * offset within a file. * * @param signatureString The ASCII string * @param offset The offset of the signature bytes. * @param isRelativeToStart Determines whether this signature is ->>>>>>> upstream/develop * relative to start. */ Signature(String signatureString, long offset, boolean isRelativeToStart) { @@ -282,24 +251,14 @@ class FileType implements Serializable { } /** -<<<<<<< HEAD - * Creates a file signatures consisting of a sequence of bytes at a -======= * Creates a file signature consisting of a sequence of bytes at a ->>>>>>> upstream/develop * specific offset within a file. If bytes correspond to an ASCII * string, use one of the other constructors so that the string is * displayed to the user instead of the raw bytes. * -<<<<<<< HEAD - * @param signatureBytes The signatures bytes. - * @param offset The offset of the signatures bytes. - * @param isRelativeToStart Determines whether this signatures is -======= * @param signatureBytes The signature bytes. * @param offset The offset of the signature bytes. * @param isRelativeToStart Determines whether this signature is ->>>>>>> upstream/develop * relative to start. */ Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) { @@ -395,6 +354,33 @@ class FileType implements Serializable { hash = 97 * hash + Objects.hashCode(this.type); return hash; } + + @Override + public String toString() { + String signatureBytesString; + if (Signature.Type.RAW == this.getType()) { + signatureBytesString = DatatypeConverter.printHexBinary(this.getSignatureBytes()); + } else { + try { + signatureBytesString = new String(this.getSignatureBytes(), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + JOptionPane.showMessageDialog(null, + ex.getLocalizedMessage(), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"), + JOptionPane.ERROR_MESSAGE); + signatureBytesString = ""; + } + } + String startOrEnd; + if(this.isRelativeToStart) { + startOrEnd = "start"; + } + else { + startOrEnd = "end"; + } + return "(" + signatureBytesString + " from " + startOrEnd + ")"; + + } } } From 79857ba9621c7d0a0c24221a81d43e2b2d282467 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 29 Mar 2016 16:13:41 -0400 Subject: [PATCH 12/29] Allowed new file types to be added. --- .../autopsy/modules/filetypeid/FileType.java | 3 +- .../FileTypeIdGlobalSettingsPanel.form | 2 +- .../FileTypeIdGlobalSettingsPanel.java | 54 +++++++++++++++++-- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 7f2aa7d6f9..7b2f145b50 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -360,6 +360,7 @@ class FileType implements Serializable { String signatureBytesString; if (Signature.Type.RAW == this.getType()) { signatureBytesString = DatatypeConverter.printHexBinary(this.getSignatureBytes()); + signatureBytesString = "0x" + signatureBytesString; } else { try { signatureBytesString = new String(this.getSignatureBytes(), "UTF-8"); @@ -378,7 +379,7 @@ class FileType implements Serializable { else { startOrEnd = "end"; } - return "(" + signatureBytesString + " from " + startOrEnd + ")"; + return "(" + signatureBytesString + ", " + offset + " from " + startOrEnd + ")"; } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index e74b45d13f..0cbb98b5e1 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -127,7 +127,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 7b67b55755..97999c0a24 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -22,6 +22,7 @@ import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.DefaultComboBoxModel; @@ -34,6 +35,7 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.xml.bind.DatatypeConverter; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; @@ -107,7 +109,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane typesListModel = new DefaultListModel<>(); typesList.setModel(typesListModel); } - + private void setSignaturesListModel() { this.signaturesListModel = new DefaultListModel<>(); signatureList.setModel(signaturesListModel); @@ -269,7 +271,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane mimeTypeTextField.setEditable(false); List signatures = fileType.getSignatures(); this.signaturesListModel.clear(); - for(Signature sig: signatures) { + for (Signature sig : signatures) { signaturesListModel.addElement(sig); } postHitCheckBox.setSelected(fileType.alertOnMatch()); @@ -528,7 +530,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(saveTypeButton) - .addGap(0, 54, Short.MAX_VALUE)))) + .addGap(0, 33, Short.MAX_VALUE)))) ); layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton}); @@ -547,9 +549,51 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane typesList.setSelectedIndex(0); } }//GEN-LAST:event_deleteTypeButtonActionPerformed - + @Messages({ + "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSigList.message=Must have at least one signature.", + "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSigList.title=Invalid Signature List"}) private void saveTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTypeButtonActionPerformed - + String typeName = mimeTypeTextField.getText(); + if (typeName.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title"), + JOptionPane.ERROR_MESSAGE); + return; + } + List sigList = new ArrayList<>(); + for (int i = 0; i < this.signaturesListModel.getSize(); i++) { + sigList.add(this.signaturesListModel.elementAt(i)); + } + if (sigList.isEmpty()) { + JOptionPane.showMessageDialog(null, + Bundle.AddFileTypeSignatureDialog_invalidSignature_message(), + Bundle.FileTypeIdGlobalSettingsPanel_JOptionPane_invalidSigList_title(), + JOptionPane.ERROR_MESSAGE); + return; + } + /** + * Get the interesting files set details. + */ + String filesSetName = ""; + if (postHitCheckBox.isSelected()) { + filesSetName = filesSetNameTextField.getText(); + } + if (postHitCheckBox.isSelected() && filesSetName.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message"), + NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title"), + JOptionPane.ERROR_MESSAGE); + return; + } + FileType fileType = new FileType(typeName, sigList, filesSetName, postHitCheckBox.isSelected()); + FileType selected = typesList.getSelectedValue(); + if (selected != null) { + fileTypes.remove(selected); + } + fileTypes.add(fileType); + updateFileTypesListModel(); + typesList.setSelectedValue(fileType, true); }//GEN-LAST:event_saveTypeButtonActionPerformed private void postHitCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postHitCheckBoxActionPerformed From 9750c10c16f8337afdeec48843e663d643aff209 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 30 Mar 2016 09:01:02 -0400 Subject: [PATCH 13/29] Fixed saving of user defined file types. --- .../filetypeid/FileTypeIdGlobalSettingsPanel.form | 3 +++ .../filetypeid/FileTypeIdGlobalSettingsPanel.java | 13 +++++++++++++ .../filetypeid/UserDefinedFileTypesManager.java | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index 0cbb98b5e1..e74750378c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -360,6 +360,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 97999c0a24..8b7f744a4d 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -292,6 +292,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane postHitCheckBox.setSelected(false); filesSetNameTextField.setText(""); //NON-NLS filesSetNameTextField.setEnabled(false); + this.signaturesListModel.clear(); enableButtons(); } @@ -443,6 +444,11 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane org.openide.awt.Mnemonics.setLocalizedText(editSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.editSigButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(deleteSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteSigButton.text")); // NOI18N + deleteSigButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteSigButtonActionPerformed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -614,6 +620,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane } }//GEN-LAST:event_addButtonMousePressed + private void deleteSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSigButtonActionPerformed + signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); + if (!this.signaturesListModel.isEmpty()) { + signatureList.setSelectedIndex(0); + } + }//GEN-LAST:event_deleteSigButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addSigButton; private javax.swing.JButton deleteSigButton; diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index de6959ef26..0f5b34ee23 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -321,7 +321,7 @@ final class UserDefinedFileTypesManager { * types. */ synchronized void setUserDefinedFileTypes(List newFileTypes) throws UserDefinedFileTypesException { - String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_XML_FILE); + String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE); writeFileTypes(newFileTypes, filePath); } From f882cd136a870fc9289ff1549ae0e364b5ab7bfb Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 30 Mar 2016 11:22:12 -0400 Subject: [PATCH 14/29] Made edit sig button work, final touches to UI. --- .../AddFileTypeSignatureDialog.java | 21 +++++++-- .../filetypeid/AddFileTypeSignaturePanel.java | 35 +++++++++++++++ .../autopsy/modules/filetypeid/FileType.java | 13 +++--- .../FileTypeIdGlobalSettingsPanel.form | 11 ++--- .../FileTypeIdGlobalSettingsPanel.java | 43 ++++++++++++------- 5 files changed, 92 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index 75a162c4da..33304a8438 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -73,7 +73,13 @@ final class AddFileTypeSignatureDialog extends JDialog { AddFileTypeSignatureDialog() { super(new JFrame(TITLE), TITLE, true); this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(); - this.display(); + this.display(true); + } + + AddFileTypeSignatureDialog(Signature toEdit) { + super(new JFrame(TITLE), TITLE, true); + this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(toEdit); + this.display(false); } /** @@ -88,8 +94,9 @@ final class AddFileTypeSignatureDialog extends JDialog { */ @Messages({ "AddFileTypeSignatureDialog.addButton.title=Add", + "AddFileTypeSignatureDialog.addButton.title2=Done", "AddFileTypeSignatureDialog.cancelButton.title=Cancel"}) - void display() { + void display(boolean add) { setLayout(new BorderLayout()); /** @@ -106,8 +113,14 @@ final class AddFileTypeSignatureDialog extends JDialog { */ add(this.addFileTypeSigPanel, BorderLayout.PAGE_START); - // Add a start ingest button. - JButton addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title()); + // Add the add/done button. + JButton addButton; + if (add) { + addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title()); + } + else { + addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title2()); + } addButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java index 3b3bd12fd9..65afa26ff9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -5,6 +5,7 @@ */ package org.sleuthkit.autopsy.modules.filetypeid; +import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; @@ -14,7 +15,9 @@ import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.xml.bind.DatatypeConverter; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; @@ -37,6 +40,11 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { customizeComponents(); } + AddFileTypeSignaturePanel(Signature toEdit) { + this(); + this.setComponentValues(toEdit); + } + /** * Does child component initialization in addition to that done by the * Matisse generated code. @@ -45,6 +53,7 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { setSignatureTypeComboBoxModel(); setOffsetRealtiveToComboBoxModel(); } + /** * Sets the model for the signature type combo box. */ @@ -67,6 +76,29 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { offsetRelativeToComboBox.setSelectedItem(START_OFFSET_RELATIVE_COMBO_BOX_ITEM); } + @Messages({"AddFileTypeSignaturePanel.signatureStringFail.text=Couldn't get signatures string"}) + private void setComponentValues(Signature toEdit) { + if (toEdit.isRelativeToStart()) { + this.offsetRelativeToComboBox.setSelectedIndex(0); + } else { + this.offsetRelativeToComboBox.setSelectedIndex(1); + } + this.offsetTextField.setText(toEdit.getOffset() + ""); + if (Signature.Type.RAW == toEdit.getType()) { + this.signatureTypeComboBox.setSelectedIndex(0); + this.signatureTextField.setText(DatatypeConverter.printHexBinary(toEdit.getSignatureBytes())); + } else { + this.signatureTypeComboBox.setSelectedIndex(1); + try { + this.signatureTextField.setText(new String(toEdit.getSignatureBytes(), "UTF-8")); + } catch (UnsupportedEncodingException ex) { + JOptionPane.showMessageDialog(null, + ex.getLocalizedMessage(), + Bundle.AddFileTypeSignaturePanel_signatureStringFail_text(), + JOptionPane.ERROR_MESSAGE); + } + } + } public Signature getSignature() { @@ -79,11 +111,13 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { * Get the signature bytes. */ String sigString = signatureTextField.getText(); + if (sigString.isEmpty()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message"), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title"), JOptionPane.ERROR_MESSAGE); + return null; } byte[] signatureBytes; @@ -107,6 +141,7 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { */ long offset; boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == START_OFFSET_RELATIVE_COMBO_BOX_ITEM; + try { offset = Long.parseUnsignedLong(offsetTextField.getText()); if (!isRelativeToStart && signatureBytes.length > offset + 1) { diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 7b2f145b50..427d08e212 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -354,7 +354,7 @@ class FileType implements Serializable { hash = 97 * hash + Objects.hashCode(this.type); return hash; } - + @Override public String toString() { String signatureBytesString; @@ -367,20 +367,19 @@ class FileType implements Serializable { } catch (UnsupportedEncodingException ex) { JOptionPane.showMessageDialog(null, ex.getLocalizedMessage(), - NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"), + Bundle.AddFileTypeSignaturePanel_signatureStringFail_text(), JOptionPane.ERROR_MESSAGE); signatureBytesString = ""; } } String startOrEnd; - if(this.isRelativeToStart) { + if (this.isRelativeToStart) { startOrEnd = "start"; - } - else { + } else { startOrEnd = "end"; } - return "(" + signatureBytesString + ", " + offset + " from " + startOrEnd + ")"; - + return signatureBytesString + ", " + offset + " bytes from " + startOrEnd; + } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index e74750378c..0ac796f92c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -3,10 +3,10 @@

- + - + @@ -92,7 +92,7 @@ - + @@ -127,7 +127,6 @@ - @@ -343,7 +342,6 @@ - @@ -353,6 +351,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 8b7f744a4d..32f243acdf 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -277,6 +277,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane postHitCheckBox.setSelected(fileType.alertOnMatch()); filesSetNameTextField.setEnabled(postHitCheckBox.isSelected()); filesSetNameTextField.setText(fileType.getFilesSetName()); + this.signatureList.setEnabled(false); + this.addSigButton.setEnabled(false); + this.deleteSigButton.setEnabled(false); + this.editSigButton.setEnabled(false); } enableButtons(); } @@ -289,6 +293,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane typesList.clearSelection(); mimeTypeTextField.setText(""); //NON-NLS mimeTypeTextField.setEditable(true); + this.signatureList.setEnabled(true); + this.addSigButton.setEnabled(true); + this.deleteSigButton.setEnabled(true); + this.editSigButton.setEnabled(true); postHitCheckBox.setSelected(false); filesSetNameTextField.setText(""); //NON-NLS filesSetNameTextField.setEnabled(false); @@ -358,8 +366,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane editSigButton = new javax.swing.JButton(); deleteSigButton = new javax.swing.JButton(); - setMaximumSize(new java.awt.Dimension(500, 300)); - setPreferredSize(new java.awt.Dimension(500, 300)); + setMaximumSize(new java.awt.Dimension(552, 297)); + setPreferredSize(new java.awt.Dimension(552, 297)); typesList.setFont(typesList.getFont().deriveFont(typesList.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); typesList.setMaximumSize(new java.awt.Dimension(150, 0)); @@ -430,11 +438,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jScrollPane1.setViewportView(signatureList); org.openide.awt.Mnemonics.setLocalizedText(addSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.addSigButton.text")); // NOI18N - addSigButton.addMouseListener(new java.awt.event.MouseAdapter() { - public void mousePressed(java.awt.event.MouseEvent evt) { - addButtonMousePressed(evt); - } - }); addSigButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addSigButtonActionPerformed(evt); @@ -442,6 +445,11 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }); org.openide.awt.Mnemonics.setLocalizedText(editSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.editSigButton.text")); // NOI18N + editSigButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + editSigButtonActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(deleteSigButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteSigButton.text")); // NOI18N deleteSigButton.addActionListener(new java.awt.event.ActionListener() { @@ -508,7 +516,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addGroup(layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(typesScrollPane) + .addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(deleteTypeButton) @@ -535,8 +543,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane .addComponent(filesSetNameLabel) .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(saveTypeButton) - .addGap(0, 33, Short.MAX_VALUE)))) + .addComponent(saveTypeButton)))) ); layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton}); @@ -608,17 +615,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }//GEN-LAST:event_postHitCheckBoxActionPerformed private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed - - }//GEN-LAST:event_addSigButtonActionPerformed - - private void addButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMousePressed if (evt.getSource().equals(this.addSigButton)) { this.addSigDialog = new AddFileTypeSignatureDialog(); if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { signaturesListModel.addElement(this.addSigDialog.getSignature()); } } - }//GEN-LAST:event_addButtonMousePressed + }//GEN-LAST:event_addSigButtonActionPerformed private void deleteSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSigButtonActionPerformed signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); @@ -627,6 +630,16 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane } }//GEN-LAST:event_deleteSigButtonActionPerformed + private void editSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSigButtonActionPerformed + if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) { + this.addSigDialog = new AddFileTypeSignatureDialog(this.signatureList.getSelectedValue()); + if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { + signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); + this.signaturesListModel.addElement(this.addSigDialog.getSignature()); + } + } + }//GEN-LAST:event_editSigButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addSigButton; private javax.swing.JButton deleteSigButton; From 7f429617d3a78633b76d91177ce08effaa340abb Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 30 Mar 2016 16:02:22 -0400 Subject: [PATCH 15/29] Fixed delete button action when nothing is selected. --- .../FileTypeIdGlobalSettingsPanel.form | 274 ++++++++++++------ .../FileTypeIdGlobalSettingsPanel.java | 15 +- 2 files changed, 200 insertions(+), 89 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index 0ac796f92c..828b7b3222 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -3,10 +3,10 @@ - + - + @@ -33,46 +33,69 @@ - - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + + + + + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -92,7 +115,7 @@ - + @@ -111,14 +134,29 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -127,6 +165,7 @@ + @@ -193,6 +232,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -238,6 +328,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -316,54 +448,32 @@ - + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 32f243acdf..6e42f7d7fa 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -21,19 +21,18 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; +import javax.swing.JList; import javax.swing.JOptionPane; -import javax.swing.ListModel; +import javax.swing.ListCellRenderer; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import javax.xml.bind.DatatypeConverter; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; @@ -624,14 +623,16 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane }//GEN-LAST:event_addSigButtonActionPerformed private void deleteSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSigButtonActionPerformed - signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); - if (!this.signaturesListModel.isEmpty()) { - signatureList.setSelectedIndex(0); + if (this.signatureList.getSelectedIndex() != -1) { + signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); + if (!this.signaturesListModel.isEmpty()) { + signatureList.setSelectedIndex(0); + } } }//GEN-LAST:event_deleteSigButtonActionPerformed private void editSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSigButtonActionPerformed - if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) { + if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) { this.addSigDialog = new AddFileTypeSignatureDialog(this.signatureList.getSelectedValue()); if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); From 98185477c0c75ab2f9476a35ac10b46e288abe47 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Thu, 31 Mar 2016 13:18:01 -0400 Subject: [PATCH 16/29] Added new mime types to manager. --- .../UserDefinedFileTypesManager.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index 0f5b34ee23..6efc662eb0 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -263,6 +263,49 @@ final class UserDefinedFileTypesManager { signatureList.add(new Signature(byteArray, 17, false)); fileType = new FileType("image/x-tga", new ArrayList<>(signatureList), "", false); //NON-NLS fileTypes.add(fileType); + + // Add rule for .ilbm + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + signatureList.add(new Signature("ILBM", 8L)); + fileType = new FileType("image/x-ilbm", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + signatureList.add(new Signature("PBM", 8L)); + fileType = new FileType("image/x-ilbm", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + + // Add rule for .webp + signatureList = new ArrayList<>(); + signatureList.add(new Signature("RIFF", 0L)); + signatureList.add(new Signature("WEBP", 8L)); + fileType = new FileType("image/webp", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + + // Add rule for .aiff + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + signatureList.add(new Signature("AIFF", 8L)); + fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + signatureList.add(new Signature("AIFC", 8L)); + fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + signatureList.add(new Signature("8SVX", 8L)); + fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + + // Add .iff + signatureList = new ArrayList<>(); + signatureList.add(new Signature("FORM", 0L)); + fileType = new FileType("application/x-iff", new ArrayList<>(signatureList), "", false); + fileTypes.add(fileType); + } // parseHexBinary() throws this if the argument passed in is not Hex catch (IllegalArgumentException e) { throw new UserDefinedFileTypesException("Error creating predefined file types", e); // From fe657a4102203fe618d4796946088572ce2fd04c Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 6 Apr 2016 15:50:03 -0400 Subject: [PATCH 17/29] Fixed hash lookup setting saving and reading process. --- .../modules/hashdatabase/HashDbManager.java | 117 ++++-------- .../HashDbSerializationSettings.java | 66 ------- .../hashdatabase/HashLookupSettings.java | 169 ++++++++++++++++++ 3 files changed, 199 insertions(+), 153 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java create mode 100755 Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index b897736d50..a7519f5da8 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -27,9 +27,6 @@ import java.util.List; import java.util.Set; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; @@ -39,9 +36,7 @@ import org.w3c.dom.NodeList; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.Serializable; -import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.logging.Level; @@ -51,8 +46,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FileUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.util.Exceptions; import org.openide.util.io.NbObjectInputStream; -import org.openide.util.io.NbObjectOutputStream; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; @@ -63,6 +58,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.ingest.IngestManager; +import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupSettings.HashDbInfo; /** * This class implements a singleton that manages the set of hash databases used @@ -70,7 +66,6 @@ import org.sleuthkit.autopsy.ingest.IngestManager; */ public class HashDbManager implements PropertyChangeListener { - private static final String ROOT_ELEMENT = "hash_sets"; //NON-NLS private static final String SET_ELEMENT = "hash_set"; //NON-NLS private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS @@ -80,8 +75,6 @@ public class HashDbManager implements PropertyChangeListener { private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS private static final String DB_SERIALIZATION_FILE_NAME = "hashDbs.settings"; - private static final String XSD_FILE_NAME = "HashsetsSchema.xsd"; //NON-NLS - private static final String ENCODING = "UTF-8"; //NON-NLS private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS private static HashDbManager instance = null; private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; @@ -488,7 +481,11 @@ public class HashDbManager implements PropertyChangeListener { * @return True on success, false otherwise. */ synchronized boolean save() { - return writeHashSetConfigurationToDisk(); + try { + return HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets)); + } catch (TskCoreException ex) { + return false; + } } /** @@ -515,65 +512,19 @@ public class HashDbManager implements PropertyChangeListener { hashDatabases.clear(); } - private boolean writeHashSetConfigurationToDisk() { - - try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(DB_SERIALIZATION_FILE_PATH))) { - HashDbSerializationSettings settings = new HashDbSerializationSettings(this.knownHashSets, this.knownBadHashSets); - out.writeObject(settings); - return true; - } catch (IOException | TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not wtite hash database settings."); - return false; - } - } - - private static void writeHashDbsToDisk(Document doc, Element rootEl, List hashDbs) { - for (HashDb db : hashDbs) { - // Get the path for the hash database before writing anything, in - // case an exception is thrown. - String path; - try { - if (db.hasIndexOnly()) { - path = db.getIndexPath(); - } else { - path = db.getDatabasePath(); - } - } catch (TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting path of hash database " + db.getHashSetName() + ", discarding from hash database configuration", ex); //NON-NLS - continue; - } - - Element setElement = doc.createElement(SET_ELEMENT); - setElement.setAttribute(SET_NAME_ATTRIBUTE, db.getHashSetName()); - setElement.setAttribute(SET_TYPE_ATTRIBUTE, db.getKnownFilesType().toString()); - setElement.setAttribute(SEARCH_DURING_INGEST_ATTRIBUTE, Boolean.toString(db.getSearchDuringIngest())); - setElement.setAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE, Boolean.toString(db.getSendIngestMessages())); - Element pathElement = doc.createElement(PATH_ELEMENT); - pathElement.setTextContent(path); - setElement.appendChild(pathElement); - rootEl.appendChild(setElement); - } - } - - private boolean hashSetsConfigurationFileExists() { - File f = new File(configFilePath); - return f.exists() && f.canRead() && f.canWrite(); - } - private boolean readHashSetsConfigurationFromDisk() { - File fileSetFile = new File(DB_SERIALIZATION_FILE_PATH); - if (fileSetFile.exists()) { - try { - try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(DB_SERIALIZATION_FILE_PATH))) { - HashDbSerializationSettings filesSetsSettings = (HashDbSerializationSettings) in.readObject(); - this.setFields(filesSetsSettings); - return true; - } - } catch (IOException | ClassNotFoundException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read hash database settings."); - return false; + + File f = new File(configFilePath); + try { + HashLookupSettings settings = HashLookupSettings.readSettings(); + if (settings != null) { + this.setFields(settings); } - } else if (hashSetsConfigurationFileExists()) { + return true; + } catch (HashLookupSettings.HashLookupSettingsException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Could not read Hash lookup settings from disk.", ex); + } + if (f.exists()) { boolean updatedSchema = false; // Open the XML document that implements the configuration file. @@ -708,14 +659,19 @@ public class HashDbManager implements PropertyChangeListener { Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); } - - writeHashSetConfigurationToDisk(); + HashLookupSettings settings; + try { + settings = new HashLookupSettings(this.knownHashSets, this.knownBadHashSets); + HashLookupSettings.writeSettings(settings); + } catch (TskCoreException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to write settings to disk.", ex); //NON-NLS + } } return true; } else { try { - this.setFields(new HashDbSerializationSettings(new ArrayList<>(), new ArrayList<>())); + this.setFields(new HashLookupSettings(new ArrayList<>(), new ArrayList<>())); } catch (TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read hash database settings."); return false; @@ -725,24 +681,11 @@ public class HashDbManager implements PropertyChangeListener { } } - private void setFields(HashDbSerializationSettings settings) { - Map knownPathMap = settings.getKnownPathMap(); - Map knownBadPathMap = settings.getKnownBadPathMap(); - for (HashDbManager.HashDb hashDb : settings.getKnownHashSets()) { + private void setFields(HashLookupSettings settings) { + List hashDbInfoList = settings.getHashDbInfoList(); + for (HashDbInfo hashDb : hashDbInfoList) { try { - addExistingHashDatabaseInternal(hashDb.getHashSetName(), knownPathMap.get(hashDb), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN); - } catch (HashDbManagerException | TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()), - NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), - JOptionPane.ERROR_MESSAGE); - } - } - for (HashDbManager.HashDb hashDb : settings.getKnownBadHashSets()) { - try { - addExistingHashDatabaseInternal(hashDb.getHashSetName(), knownBadPathMap.get(hashDb), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), HashDb.KnownFilesType.KNOWN_BAD); + addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()) , hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType()); } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS JOptionPane.showMessageDialog(null, diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java deleted file mode 100755 index f367707c2b..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbSerializationSettings.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.modules.hashdatabase; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Class to represent the settings to be serialized for hash databases - */ -class HashDbSerializationSettings implements Serializable { - - private static final long serialVersionUID = 1L; - private final List knownHashSets; - private final List knownBadHashSets; - private final Map knownPathMap = new HashMap<>(); - private final Map knownBadPathMap = new HashMap<>(); - - /** - * Constructs a settings object to be serialized for hash dbs - * @param knownHashSets - * @param knownBadHashSets - */ - HashDbSerializationSettings(List knownHashSets, List knownBadHashSets) throws TskCoreException { - this.knownHashSets = knownHashSets; - this.knownBadHashSets = knownBadHashSets; - for(HashDbManager.HashDb hashDb: this.knownHashSets) { - knownPathMap.put(hashDb, hashDb.getDatabasePath()); - } - - for(HashDbManager.HashDb hashDb: this.knownBadHashSets) { - knownBadPathMap.put(hashDb, hashDb.getDatabasePath()); - } - } - - List getKnownHashSets() { - return this.knownHashSets; - } - - /** - * @return the knownBadHashSets - */ - public List getKnownBadHashSets() { - return knownBadHashSets; - } - - /** - * @return the knownPathMap - */ - public Map getKnownPathMap() { - return knownPathMap; - } - - /** - * @return the knownBadPathMap - */ - public Map getKnownBadPathMap() { - return knownBadPathMap; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java new file mode 100755 index 0000000000..82a7b8afcf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -0,0 +1,169 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.modules.hashdatabase; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import javax.swing.JOptionPane; +import org.apache.commons.io.FileUtils; +import org.openide.util.NbBundle; +import org.openide.util.io.NbObjectInputStream; +import org.openide.util.io.NbObjectOutputStream; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.coreutils.XMLUtil; +import org.sleuthkit.datamodel.TskCoreException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * Class to represent the settings to be serialized for hash databases + */ +class HashLookupSettings implements Serializable { + + private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; + private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; + + private static final long serialVersionUID = 1L; + private final List hashDbInfoList; + + /** + * Constructs a settings object to be serialized for hash dbs + * + * @param knownHashSets + * @param knownBadHashSets + */ + HashLookupSettings(List knownHashSets, List knownBadHashSets) throws TskCoreException { + hashDbInfoList = new ArrayList<>(); + for (HashDbManager.HashDb hashDb : knownHashSets) { + if (hashDb.hasIndexOnly()) { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); + } else { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + } + } + + for (HashDbManager.HashDb hashDb : knownBadHashSets) { + if (hashDb.hasIndexOnly()) { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); + } else { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + } + } + } + + /** + * @return the hashDbInfoList + */ + public List getHashDbInfoList() { + return hashDbInfoList; + } + + public static HashLookupSettings readSettings() throws HashLookupSettingsException { + File fileSetFile = new File(SERIALIZATION_FILE_PATH); + if (fileSetFile.exists()) { + try { + try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) { + HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject(); + return filesSetsSettings; + } + } catch (IOException | ClassNotFoundException ex) { + throw new HashLookupSettingsException("Could not read hash database settings.", ex); + } + } + return null; + } + + static boolean writeSettings(HashLookupSettings settings) { + try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(SERIALIZATION_FILE_PATH))) { + out.writeObject(settings); + return true; + } catch (Exception ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not wtite hash database settings."); + return false; + } + } + + static final class HashDbInfo implements Serializable { + + private static final long serialVersionUID = 1L; + private String hashSetName; + private HashDbManager.HashDb.KnownFilesType knownFilesType; + private boolean searchDuringIngest; + private boolean sendIngestMessages; + private String path; + + public HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) { + this.hashSetName = hashSetName; + this.knownFilesType = knownFilesType; + this.searchDuringIngest = searchDuringIngest; + this.sendIngestMessages = sendIngestMessages; + this.path = path; + } + + /** + * @return the hashSetName + */ + public String getHashSetName() { + return hashSetName; + } + + /** + * @return the knownFilesType + */ + public HashDbManager.HashDb.KnownFilesType getKnownFilesType() { + return knownFilesType; + } + + /** + * @return the searchDuringIngest + */ + public boolean getSearchDuringIngest() { + return searchDuringIngest; + } + + /** + * @return the sendIngestMessages + */ + public boolean getSendIngestMessages() { + return sendIngestMessages; + } + + /** + * @return the path + */ + public String getPath() { + return path; + } + } + + /** + * Used to translate more implementation-details-specific exceptions (which + * are logged by this class) into more generic exceptions for propagation to + * clients of the user-defined file types manager. + */ + static class HashLookupSettingsException extends Exception { + + private static final long serialVersionUID = 1L; + + HashLookupSettingsException(String message) { + super(message); + } + + HashLookupSettingsException(String message, Throwable throwable) { + super(message, throwable); + } + } +} From becb03058bedc0343ed7ad538859538071001f34 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Thu, 7 Apr 2016 11:41:09 -0400 Subject: [PATCH 18/29] Moved xml to settings class. --- .../modules/hashdatabase/HashDbManager.java | 159 +------------- .../hashdatabase/HashLookupSettings.java | 205 +++++++++++++++++- 2 files changed, 205 insertions(+), 159 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index a7519f5da8..e66225063a 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -35,7 +35,6 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; -import java.io.FileInputStream; import java.io.Serializable; import java.util.Objects; import java.util.concurrent.ExecutionException; @@ -46,8 +45,6 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FileUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; -import org.openide.util.Exceptions; -import org.openide.util.io.NbObjectInputStream; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; @@ -523,161 +520,7 @@ public class HashDbManager implements PropertyChangeListener { return true; } catch (HashLookupSettings.HashLookupSettingsException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Could not read Hash lookup settings from disk.", ex); - } - if (f.exists()) { - boolean updatedSchema = false; - - // Open the XML document that implements the configuration file. - final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); - if (doc == null) { - return false; - } - - // Get the root element. - Element root = doc.getDocumentElement(); - if (root == null) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS - return false; - } - - // Get the hash set elements. - NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); - int numSets = setsNList.getLength(); - if (numSets == 0) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS - } - - // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of - // a particular hash database is not well-formed. - String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - for (int i = 0; i < numSets; ++i) { - Element setEl = (Element) setsNList.item(i); - - String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); - if (hashSetName.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - - // Handle configurations saved before duplicate hash set names were not permitted. - if (hashSetNames.contains(hashSetName)) { - int suffix = 0; - String newHashSetName; - do { - ++suffix; - newHashSetName = hashSetName + suffix; - } while (hashSetNames.contains(newHashSetName)); - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.replacingDuplicateHashsetNameMsg", - hashSetName, newHashSetName), - NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), - JOptionPane.ERROR_MESSAGE); - hashSetName = newHashSetName; - } - - String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); - if (knownFilesType.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - - // Handle legacy known files types. - if (knownFilesType.equals("NSRL")) { //NON-NLS - knownFilesType = HashDb.KnownFilesType.KNOWN.toString(); - updatedSchema = true; - } - - final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); - - final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); - - String dbPath; - NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); - if (pathsNList.getLength() > 0) { - Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. - - // Check for legacy path number attribute. - String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); - if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { - updatedSchema = true; - } - - dbPath = pathEl.getTextContent(); - if (dbPath.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - dbPath = getValidFilePath(hashSetName, dbPath); - - if (null != dbPath) { - try { - addExistingHashDatabaseInternal(hashSetName, dbPath, seearchDuringIngestFlag, sendIngestMessagesFlag, HashDb.KnownFilesType.valueOf(knownFilesType)); - } catch (HashDbManagerException | TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.unableToOpenHashDbMsg", dbPath), - NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), - JOptionPane.ERROR_MESSAGE); - } - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS - } - } - - if (updatedSchema) { - String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS - String messageBoxTitle = NbBundle.getMessage(this.getClass(), - "HashDbManager.msgBoxTitle.confFileFmtChanged"); - String baseMessage = NbBundle.getMessage(this.getClass(), - "HashDbManager.baseMessage.updatedFormatHashDbConfig"); - try { - FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "HashDbManager.savedBackupOfOldConfigMsg", - baseMessage, backupFilePath), - messageBoxTitle, - JOptionPane.INFORMATION_MESSAGE); - } catch (IOException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS - JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); - } - HashLookupSettings settings; - try { - settings = new HashLookupSettings(this.knownHashSets, this.knownBadHashSets); - HashLookupSettings.writeSettings(settings); - } catch (TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to write settings to disk.", ex); //NON-NLS - } - } - - return true; - } else { - try { - this.setFields(new HashLookupSettings(new ArrayList<>(), new ArrayList<>())); - } catch (TskCoreException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read hash database settings."); - return false; - } - - return true; + return false; } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index 82a7b8afcf..76b79d1e06 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -15,7 +15,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; +import javax.swing.JFileChooser; import javax.swing.JOptionPane; +import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.commons.io.FileUtils; import org.openide.util.NbBundle; import org.openide.util.io.NbObjectInputStream; @@ -35,10 +37,25 @@ class HashLookupSettings implements Serializable { private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; + private static final String SET_ELEMENT = "hash_set"; //NON-NLS + private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS + private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS + private static final String SEARCH_DURING_INGEST_ATTRIBUTE = "use_for_ingest"; //NON-NLS + private static final String SEND_INGEST_MESSAGES_ATTRIBUTE = "show_inbox_messages"; //NON-NLS + private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS + private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS + private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS + private static final String DB_SERIALIZATION_FILE_NAME = "hashDbs.settings"; + private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS + private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; private static final long serialVersionUID = 1L; private final List hashDbInfoList; + public HashLookupSettings(List hashDbInfoList) { + this.hashDbInfoList = hashDbInfoList; + } + /** * Constructs a settings object to be serialized for hash dbs * @@ -71,8 +88,55 @@ class HashLookupSettings implements Serializable { return hashDbInfoList; } + private static String getValidFilePath(String hashSetName, String configuredPath) { + // Check the configured path. + File database = new File(configuredPath); + if (database.exists()) { + return configuredPath; + } + + // Give the user an opportunity to find the desired file. + String newPath = null; + if (JOptionPane.showConfirmDialog(null, + NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.dlgMsg.dbNotFoundAtLoc", + hashSetName, configuredPath), + NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.dlgTitle.MissingDb"), + JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + newPath = searchForFile(); + if (null != newPath && !newPath.isEmpty()) { + database = new File(newPath); + if (!database.exists()) { + newPath = null; + } + } + } + return newPath; + } + + private static String searchForFile() { + String filePath = null; + JFileChooser fc = new JFileChooser(); + fc.setDragEnabled(false); + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + String[] EXTENSION = new String[]{"txt", "idx", "hash", "Hash", "kdb"}; //NON-NLS + FileNameExtensionFilter filter = new FileNameExtensionFilter( + NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.fileNameExtensionFilter.title"), EXTENSION); + fc.setFileFilter(filter); + fc.setMultiSelectionEnabled(false); + if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File f = fc.getSelectedFile(); + try { + filePath = f.getCanonicalPath(); + } catch (IOException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Couldn't get selected file path", ex); //NON-NLS + } + } + return filePath; + } + public static HashLookupSettings readSettings() throws HashLookupSettingsException { File fileSetFile = new File(SERIALIZATION_FILE_PATH); + File f = new File(configFilePath); if (fileSetFile.exists()) { try { try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) { @@ -82,8 +146,147 @@ class HashLookupSettings implements Serializable { } catch (IOException | ClassNotFoundException ex) { throw new HashLookupSettingsException("Could not read hash database settings.", ex); } + } else { + if (f.exists()) { + boolean updatedSchema = false; + + // Open the XML document that implements the configuration file. + final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); + if (doc == null) { + return null; + } + + // Get the root element. + Element root = doc.getDocumentElement(); + if (root == null) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS + return null; + } + + // Get the hash set elements. + NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); + int numSets = setsNList.getLength(); + if (numSets == 0) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS + } + + // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of + // a particular hash database is not well-formed. + String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + List hashSetNames = new ArrayList<>(); + List hashDbInfoList = new ArrayList<>(); + for (int i = 0; i < numSets; ++i) { + Element setEl = (Element) setsNList.item(i); + + String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); + if (hashSetName.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + + // Handle configurations saved before duplicate hash set names were not permitted. + if (hashSetNames.contains(hashSetName)) { + int suffix = 0; + String newHashSetName; + do { + ++suffix; + newHashSetName = hashSetName + suffix; + } while (hashSetNames.contains(newHashSetName)); + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.replacingDuplicateHashsetNameMsg", + hashSetName, newHashSetName), + NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.openHashDbErr"), + JOptionPane.ERROR_MESSAGE); + hashSetName = newHashSetName; + } + + String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); + if (knownFilesType.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + + // Handle legacy known files types. + if (knownFilesType.equals("NSRL")) { //NON-NLS + knownFilesType = HashDbManager.HashDb.KnownFilesType.KNOWN.toString(); + updatedSchema = true; + } + + final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + Boolean searchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); + + final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i); + continue; + } + Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); + + String dbPath; + NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); + if (pathsNList.getLength() > 0) { + Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. + + // Check for legacy path number attribute. + String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); + if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { + updatedSchema = true; + } + + dbPath = pathEl.getTextContent(); + if (dbPath.isEmpty()) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); + continue; + } + } else { + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); + continue; + } + dbPath = getValidFilePath(hashSetName, dbPath); + + if (null != dbPath) { + hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), + searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); + hashSetNames.add(hashSetName); + } else { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS + } + } + + if (updatedSchema) { + String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS + String messageBoxTitle = NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.msgBoxTitle.confFileFmtChanged"); + String baseMessage = NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.baseMessage.updatedFormatHashDbConfig"); + try { + FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.savedBackupOfOldConfigMsg", + baseMessage, backupFilePath), + messageBoxTitle, + JOptionPane.INFORMATION_MESSAGE); + } catch (IOException ex) { + Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS + JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); + } + HashLookupSettings settings; + settings = new HashLookupSettings(hashDbInfoList); + HashLookupSettings.writeSettings(settings); + } + return new HashLookupSettings(hashDbInfoList); + } + else { + return null; + } } - return null; } static boolean writeSettings(HashLookupSettings settings) { From 5122902e326eb8e1e1bd8b2f6920684700b6acfc Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 8 Apr 2016 08:38:10 -0400 Subject: [PATCH 19/29] Semantics changes to hash db serialization. --- .../modules/hashdatabase/HashDbManager.java | 79 ++++++---- .../hashdatabase/HashLookupSettings.java | 140 +++++++----------- 2 files changed, 101 insertions(+), 118 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index e66225063a..9f91e01060 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 - 2014 Basis Technology Corp. + * Copyright 2011 - 2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,23 +28,18 @@ import java.util.Set; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.coreutils.PlatformUtil; -import org.sleuthkit.autopsy.coreutils.XMLUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; -import java.io.Serializable; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.FileUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; @@ -63,19 +58,8 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupSettings.HashDbInfo; */ public class HashDbManager implements PropertyChangeListener { - private static final String SET_ELEMENT = "hash_set"; //NON-NLS - private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS - private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS - private static final String SEARCH_DURING_INGEST_ATTRIBUTE = "use_for_ingest"; //NON-NLS - private static final String SEND_INGEST_MESSAGES_ATTRIBUTE = "show_inbox_messages"; //NON-NLS - private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS - private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS - private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS - private static final String DB_SERIALIZATION_FILE_NAME = "hashDbs.settings"; private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS private static HashDbManager instance = null; - private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; - private final String DB_SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + DB_SERIALIZATION_FILE_NAME; private List knownHashSets = new ArrayList<>(); private List knownBadHashSets = new ArrayList<>(); private Set hashSetNames = new HashSet<>(); @@ -107,8 +91,12 @@ public class HashDbManager implements PropertyChangeListener { changeSupport.addPropertyChangeListener(listener); } + public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { + changeSupport.removePropertyChangeListener(listener); + } + private HashDbManager() { - readHashSetsConfigurationFromDisk(); + loadHashsetsConfiguration(); } /** @@ -122,6 +110,8 @@ public class HashDbManager implements PropertyChangeListener { public class HashDbManagerException extends Exception { + private static final long serialVersionUID = 1L; + private HashDbManagerException(String message) { super(message); } @@ -480,7 +470,7 @@ public class HashDbManager implements PropertyChangeListener { synchronized boolean save() { try { return HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets)); - } catch (TskCoreException ex) { + } catch (HashLookupSettings.HashLookupSettingsException ex) { return false; } } @@ -495,7 +485,7 @@ public class HashDbManager implements PropertyChangeListener { hashSetNames.clear(); hashSetPaths.clear(); - readHashSetsConfigurationFromDisk(); + loadHashsetsConfiguration(); } private void closeHashDatabases(List hashDatabases) { @@ -509,13 +499,11 @@ public class HashDbManager implements PropertyChangeListener { hashDatabases.clear(); } - private boolean readHashSetsConfigurationFromDisk() { - - File f = new File(configFilePath); + private boolean loadHashsetsConfiguration() { try { HashLookupSettings settings = HashLookupSettings.readSettings(); if (settings != null) { - this.setFields(settings); + this.configureSettings(settings); } return true; } catch (HashLookupSettings.HashLookupSettingsException ex) { @@ -524,11 +512,18 @@ public class HashDbManager implements PropertyChangeListener { } } - private void setFields(HashLookupSettings settings) { - List hashDbInfoList = settings.getHashDbInfoList(); + @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}"}) + private void configureSettings(HashLookupSettings settings) { + List hashDbInfoList = settings.getHashDbInfo(); for (HashDbInfo hashDb : hashDbInfoList) { try { - addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()) , hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType()); + String dbPath = this.getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()); + if (dbPath != null) { + addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType()); + } + else { + logger.log(Level.WARNING, Bundle.HashDbManager_noDbPath_message(hashDb.getHashSetName())); + } } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS JOptionPane.showMessageDialog(null, @@ -590,7 +585,7 @@ public class HashDbManager implements PropertyChangeListener { * Instances of this class represent hash databases used to classify files * as known or know bad. */ - public static class HashDb implements Serializable { + public static class HashDb { /** * Indicates how files with hashes stored in a particular hash database @@ -807,6 +802,30 @@ public class HashDbManager implements PropertyChangeListener { code = 47 * code + Objects.hashCode(this.knownFilesType); return code; } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final HashDb other = (HashDb) obj; + if (!Objects.equals(this.hashSetName, other.hashSetName)) { + return false; + } + if (this.searchDuringIngest != other.searchDuringIngest) { + return false; + } + if (this.sendIngestMessages != other.sendIngestMessages) { + return false; + } + if (this.knownFilesType != other.knownFilesType) { + return false; + } + return true; + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index 76b79d1e06..63a147a8da 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011 - 2016 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.modules.hashdatabase; @@ -11,9 +24,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.logging.Level; import javax.swing.JFileChooser; import javax.swing.JOptionPane; @@ -45,14 +56,12 @@ class HashLookupSettings implements Serializable { private static final String PATH_ELEMENT = "hash_set_path"; //NON-NLS private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS - private static final String DB_SERIALIZATION_FILE_NAME = "hashDbs.settings"; - private static final String HASH_DATABASE_FILE_EXTENSON = "kdb"; //NON-NLS private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; private static final long serialVersionUID = 1L; private final List hashDbInfoList; - public HashLookupSettings(List hashDbInfoList) { + HashLookupSettings(List hashDbInfoList) { this.hashDbInfoList = hashDbInfoList; } @@ -62,21 +71,29 @@ class HashLookupSettings implements Serializable { * @param knownHashSets * @param knownBadHashSets */ - HashLookupSettings(List knownHashSets, List knownBadHashSets) throws TskCoreException { + HashLookupSettings(List knownHashSets, List knownBadHashSets) throws HashLookupSettingsException { hashDbInfoList = new ArrayList<>(); for (HashDbManager.HashDb hashDb : knownHashSets) { - if (hashDb.hasIndexOnly()) { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); - } else { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + try { + if (hashDb.hasIndexOnly()) { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); + } else { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + } + } catch (TskCoreException ex) { + throw new HashLookupSettingsException("Couldn't add hash database named: " + hashDb.getHashSetName(), ex); } } for (HashDbManager.HashDb hashDb : knownBadHashSets) { - if (hashDb.hasIndexOnly()) { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); - } else { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + try { + if (hashDb.hasIndexOnly()) { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); + } else { + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + } + } catch (TskCoreException ex) { + throw new HashLookupSettingsException("Couldn't add hash database named: " + hashDb.getHashSetName(), ex); } } } @@ -84,57 +101,11 @@ class HashLookupSettings implements Serializable { /** * @return the hashDbInfoList */ - public List getHashDbInfoList() { + List getHashDbInfo() { return hashDbInfoList; } - private static String getValidFilePath(String hashSetName, String configuredPath) { - // Check the configured path. - File database = new File(configuredPath); - if (database.exists()) { - return configuredPath; - } - - // Give the user an opportunity to find the desired file. - String newPath = null; - if (JOptionPane.showConfirmDialog(null, - NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.dlgMsg.dbNotFoundAtLoc", - hashSetName, configuredPath), - NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.dlgTitle.MissingDb"), - JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { - newPath = searchForFile(); - if (null != newPath && !newPath.isEmpty()) { - database = new File(newPath); - if (!database.exists()) { - newPath = null; - } - } - } - return newPath; - } - - private static String searchForFile() { - String filePath = null; - JFileChooser fc = new JFileChooser(); - fc.setDragEnabled(false); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); - String[] EXTENSION = new String[]{"txt", "idx", "hash", "Hash", "kdb"}; //NON-NLS - FileNameExtensionFilter filter = new FileNameExtensionFilter( - NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.fileNameExtensionFilter.title"), EXTENSION); - fc.setFileFilter(filter); - fc.setMultiSelectionEnabled(false); - if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - File f = fc.getSelectedFile(); - try { - filePath = f.getCanonicalPath(); - } catch (IOException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Couldn't get selected file path", ex); //NON-NLS - } - } - return filePath; - } - - public static HashLookupSettings readSettings() throws HashLookupSettingsException { + static HashLookupSettings readSettings() throws HashLookupSettingsException { File fileSetFile = new File(SERIALIZATION_FILE_PATH); File f = new File(configFilePath); if (fileSetFile.exists()) { @@ -170,7 +141,7 @@ class HashLookupSettings implements Serializable { Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS } - // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of + // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of // a particular hash database is not well-formed. String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS @@ -248,15 +219,9 @@ class HashLookupSettings implements Serializable { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); continue; } - dbPath = getValidFilePath(hashSetName, dbPath); - - if (null != dbPath) { - hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), - searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); - hashSetNames.add(hashSetName); - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i); //NON-NLS - } + hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), + searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); + hashSetNames.add(hashSetName); } if (updatedSchema) { @@ -282,8 +247,7 @@ class HashLookupSettings implements Serializable { HashLookupSettings.writeSettings(settings); } return new HashLookupSettings(hashDbInfoList); - } - else { + } else { return null; } } @@ -302,13 +266,13 @@ class HashLookupSettings implements Serializable { static final class HashDbInfo implements Serializable { private static final long serialVersionUID = 1L; - private String hashSetName; - private HashDbManager.HashDb.KnownFilesType knownFilesType; - private boolean searchDuringIngest; - private boolean sendIngestMessages; - private String path; + private final String hashSetName; + private final HashDbManager.HashDb.KnownFilesType knownFilesType; + private final boolean searchDuringIngest; + private final boolean sendIngestMessages; + private final String path; - public HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) { + HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) { this.hashSetName = hashSetName; this.knownFilesType = knownFilesType; this.searchDuringIngest = searchDuringIngest; @@ -319,35 +283,35 @@ class HashLookupSettings implements Serializable { /** * @return the hashSetName */ - public String getHashSetName() { + String getHashSetName() { return hashSetName; } /** * @return the knownFilesType */ - public HashDbManager.HashDb.KnownFilesType getKnownFilesType() { + HashDbManager.HashDb.KnownFilesType getKnownFilesType() { return knownFilesType; } /** * @return the searchDuringIngest */ - public boolean getSearchDuringIngest() { + boolean getSearchDuringIngest() { return searchDuringIngest; } /** * @return the sendIngestMessages */ - public boolean getSendIngestMessages() { + boolean getSendIngestMessages() { return sendIngestMessages; } /** * @return the path */ - public String getPath() { + String getPath() { return path; } } From cb19a0c555b44381c345ff3147dfe383b7769f23 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 8 Apr 2016 09:39:36 -0400 Subject: [PATCH 20/29] Made hashset configuration save if malformed file is currently there. --- .../modules/hashdatabase/HashDbManager.java | 32 +++++++++++++------ .../hashdatabase/HashLookupSettings.java | 2 -- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 9f91e01060..b1d8f4795d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -499,30 +499,30 @@ public class HashDbManager implements PropertyChangeListener { hashDatabases.clear(); } - private boolean loadHashsetsConfiguration() { + private void loadHashsetsConfiguration() { try { HashLookupSettings settings = HashLookupSettings.readSettings(); if (settings != null) { this.configureSettings(settings); } - return true; } catch (HashLookupSettings.HashLookupSettingsException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Could not read Hash lookup settings from disk.", ex); - return false; } } - @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}"}) + @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}", + "HashDbManager.noOverwrite.message=Could not overwrite hash database settings."}) private void configureSettings(HashLookupSettings settings) { + boolean missedPath = false; List hashDbInfoList = settings.getHashDbInfo(); for (HashDbInfo hashDb : hashDbInfoList) { try { String dbPath = this.getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()); if (dbPath != null) { addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType()); - } - else { + } else { logger.log(Level.WARNING, Bundle.HashDbManager_noDbPath_message(hashDb.getHashSetName())); + missedPath = true; } } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS @@ -531,6 +531,14 @@ public class HashDbManager implements PropertyChangeListener { "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()), NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), JOptionPane.ERROR_MESSAGE); + missedPath = true; + } + } + if (missedPath) { + try { + HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets)); + } catch (HashLookupSettings.HashLookupSettingsException ex) { + logger.log(Level.WARNING, Bundle.HashDbManager_noOverwrite_message()); } } } @@ -614,11 +622,11 @@ public class HashDbManager implements PropertyChangeListener { INDEXING_DONE } private static final long serialVersionUID = 1L; - private int handle; - private String hashSetName; + private final int handle; + private final String hashSetName; private boolean searchDuringIngest; private boolean sendIngestMessages; - private KnownFilesType knownFilesType; + private final KnownFilesType knownFilesType; private boolean indexing; private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); @@ -633,6 +641,8 @@ public class HashDbManager implements PropertyChangeListener { /** * Adds a listener for the events defined in HashDb.Event. + * + * @param pcl */ public void addPropertyChangeListener(PropertyChangeListener pcl) { propertyChangeSupport.addPropertyChangeListener(pcl); @@ -640,6 +650,8 @@ public class HashDbManager implements PropertyChangeListener { /** * Removes a listener for the events defined in HashDb.Event. + * + * @param pcl */ public void removePropertyChangeListener(PropertyChangeListener pcl) { propertyChangeSupport.removePropertyChangeListener(pcl); @@ -681,6 +693,8 @@ public class HashDbManager implements PropertyChangeListener { * Indicates whether the hash database accepts updates. * * @return True if the database accepts updates, false otherwise. + * + * @throws org.sleuthkit.datamodel.TskCoreException */ public boolean isUpdateable() throws TskCoreException { return SleuthkitJNI.isUpdateableHashDatabase(this.handle); diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index 63a147a8da..8694d37a83 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -26,9 +26,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; -import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.commons.io.FileUtils; import org.openide.util.NbBundle; import org.openide.util.io.NbObjectInputStream; From 1bdf41c6bad9d50465b1e49a306b9d2fb5dc9947 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 8 Apr 2016 10:59:59 -0400 Subject: [PATCH 21/29] Fixed imports. --- .../sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index b1d8f4795d..e3bd862bb1 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -38,7 +38,6 @@ import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; -import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; From 974821ed4ec16702025c4eaf9bb7aafc3dea96cb Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Mon, 11 Apr 2016 16:26:06 -0400 Subject: [PATCH 22/29] Semantics changes to HashLookupSettings --- .../hashdatabase/HashLookupSettings.java | 340 ++++++++++-------- 1 file changed, 186 insertions(+), 154 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index 8694d37a83..8107add374 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -31,6 +31,7 @@ import org.apache.commons.io.FileUtils; import org.openide.util.NbBundle; import org.openide.util.io.NbObjectInputStream; import org.openide.util.io.NbObjectOutputStream; +import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; @@ -40,12 +41,12 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** - * Class to represent the settings to be serialized for hash databases + * Class to represent the settings to be serialized for hash lookup. */ -class HashLookupSettings implements Serializable { - - private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; - private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; +final class HashLookupSettings implements Serializable { + + private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; //NON-NLS + private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; //NON-NLS private static final String SET_ELEMENT = "hash_set"; //NON-NLS private static final String SET_NAME_ATTRIBUTE = "name"; //NON-NLS private static final String SET_TYPE_ATTRIBUTE = "type"; //NON-NLS @@ -55,41 +56,37 @@ class HashLookupSettings implements Serializable { private static final String LEGACY_PATH_NUMBER_ATTRIBUTE = "number"; //NON-NLS private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; - + private static final Logger logger = Logger.getLogger(HashDbManager.class.getName()); + private static final long serialVersionUID = 1L; private final List hashDbInfoList; - + HashLookupSettings(List hashDbInfoList) { this.hashDbInfoList = hashDbInfoList; } /** - * Constructs a settings object to be serialized for hash dbs + * Constructs a settings object to be serialized for hash lookups * * @param knownHashSets * @param knownBadHashSets */ HashLookupSettings(List knownHashSets, List knownBadHashSets) throws HashLookupSettingsException { hashDbInfoList = new ArrayList<>(); - for (HashDbManager.HashDb hashDb : knownHashSets) { + this.addHashesToList(knownHashSets); + this.addHashesToList(knownBadHashSets); + } + + private void addHashesToList(List hashSetList) throws HashLookupSettingsException { + for (HashDbManager.HashDb hashDb : hashSetList) { try { + String dbPath; if (hashDb.hasIndexOnly()) { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); + dbPath = hashDb.getIndexPath(); } else { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); - } - } catch (TskCoreException ex) { - throw new HashLookupSettingsException("Couldn't add hash database named: " + hashDb.getHashSetName(), ex); - } - } - - for (HashDbManager.HashDb hashDb : knownBadHashSets) { - try { - if (hashDb.hasIndexOnly()) { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getIndexPath())); - } else { - hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getDatabasePath())); + dbPath = hashDb.getDatabasePath(); } + hashDbInfoList.add(new HashDbInfo(hashDb.getHashSetName(), hashDb.getKnownFilesType(), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), dbPath)); } catch (TskCoreException ex) { throw new HashLookupSettingsException("Couldn't add hash database named: " + hashDb.getHashSetName(), ex); } @@ -97,71 +94,84 @@ class HashLookupSettings implements Serializable { } /** + * Gets the list of hash db info that this settings contains + * * @return the hashDbInfoList */ List getHashDbInfo() { return hashDbInfoList; } - + static HashLookupSettings readSettings() throws HashLookupSettingsException { File fileSetFile = new File(SERIALIZATION_FILE_PATH); - File f = new File(configFilePath); if (fileSetFile.exists()) { - try { - try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) { - HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject(); - return filesSetsSettings; - } - } catch (IOException | ClassNotFoundException ex) { - throw new HashLookupSettingsException("Could not read hash database settings.", ex); + return readSerializedSettings(); + } + return readXmlSettings(); + + } + + private static HashLookupSettings readSerializedSettings() throws HashLookupSettingsException { + try { + try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) { + HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject(); + return filesSetsSettings; } - } else { - if (f.exists()) { - boolean updatedSchema = false; + } catch (IOException | ClassNotFoundException ex) { + throw new HashLookupSettingsException("Could not read hash database settings.", ex); + } + } + + private static HashLookupSettings readXmlSettings() throws HashLookupSettingsException { + File xmlFile = new File(configFilePath); + if (xmlFile.exists()) { + boolean updatedSchema = false; - // Open the XML document that implements the configuration file. - final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); - if (doc == null) { - return null; + // Open the XML document that implements the configuration file. + final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); + if (doc == null) { + return null; + } + + // Get the root element. + Element root = doc.getDocumentElement(); + if (root == null) { + logger.log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS + return null; + } + + // Get the hash set elements. + NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); + int numSets = setsNList.getLength(); + if (numSets == 0) { + logger.log(Level.WARNING, "No element hash_set exists."); //NON-NLS + } + + // Create HashDbInfo objects for each hash set element. Throws on malformed xml. + String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + List hashSetNames = new ArrayList<>(); + List hashDbInfoList = new ArrayList<>(); + for (int i = 0; i < numSets; ++i) { + Element setEl = (Element) setsNList.item(i); + + String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); + if (hashSetName.isEmpty()) { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); } - // Get the root element. - Element root = doc.getDocumentElement(); - if (root == null) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS - return null; - } - - // Get the hash set elements. - NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); - int numSets = setsNList.getLength(); - if (numSets == 0) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists."); //NON-NLS - } - - // Create HashDb objects for each hash set element. Skip to the next hash database if the definition of - // a particular hash database is not well-formed. - String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - List hashSetNames = new ArrayList<>(); - List hashDbInfoList = new ArrayList<>(); - for (int i = 0; i < numSets; ++i) { - Element setEl = (Element) setsNList.item(i); - - String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); - if (hashSetName.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - - // Handle configurations saved before duplicate hash set names were not permitted. - if (hashSetNames.contains(hashSetName)) { - int suffix = 0; - String newHashSetName; - do { - ++suffix; - newHashSetName = hashSetName + suffix; - } while (hashSetNames.contains(newHashSetName)); + // Handle configurations saved before duplicate hash set names were not permitted. + if (hashSetNames.contains(hashSetName)) { + int suffix = 0; + String newHashSetName; + do { + ++suffix; + newHashSetName = hashSetName + suffix; + } while (hashSetNames.contains(newHashSetName)); + logger.log(Level.INFO, NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.replacingDuplicateHashsetNameMsg", + hashSetName, newHashSetName)); + if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.replacingDuplicateHashsetNameMsg", @@ -170,106 +180,118 @@ class HashLookupSettings implements Serializable { JOptionPane.ERROR_MESSAGE); hashSetName = newHashSetName; } - - String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); - if (knownFilesType.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - - // Handle legacy known files types. - if (knownFilesType.equals("NSRL")) { //NON-NLS - knownFilesType = HashDbManager.HashDb.KnownFilesType.KNOWN.toString(); - updatedSchema = true; - } - - final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean searchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); - - final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); - if (searchDuringIngest.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i); - continue; - } - Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); - - String dbPath; - NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); - if (pathsNList.getLength() > 0) { - Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. - - // Check for legacy path number attribute. - String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); - if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { - updatedSchema = true; - } - - dbPath = pathEl.getTextContent(); - if (dbPath.isEmpty()) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - } else { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i); - continue; - } - hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), - searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); - hashSetNames.add(hashSetName); + } + + String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); + if (knownFilesType.isEmpty()) { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); } - if (updatedSchema) { - String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS - String messageBoxTitle = NbBundle.getMessage(HashLookupSettings.class, - "HashDbManager.msgBoxTitle.confFileFmtChanged"); - String baseMessage = NbBundle.getMessage(HashLookupSettings.class, - "HashDbManager.baseMessage.updatedFormatHashDbConfig"); - try { - FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); + // Handle legacy known files types. + if (knownFilesType.equals("NSRL")) { //NON-NLS + knownFilesType = HashDbManager.HashDb.KnownFilesType.KNOWN.toString(); + updatedSchema = true; + } + + final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + } + Boolean searchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); + + final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); + if (searchDuringIngest.isEmpty()) { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + } + Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); + + String dbPath; + NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); + if (pathsNList.getLength() > 0) { + Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one. + + // Check for legacy path number attribute. + String legacyPathNumber = pathEl.getAttribute(LEGACY_PATH_NUMBER_ATTRIBUTE); + if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { + updatedSchema = true; + } + + dbPath = pathEl.getTextContent(); + if (dbPath.isEmpty()) { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + } + } else { + throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + } + hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), + searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); + hashSetNames.add(hashSetName); + } + + if (updatedSchema) { + String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS + String messageBoxTitle = NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.msgBoxTitle.confFileFmtChanged"); + String baseMessage = NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.baseMessage.updatedFormatHashDbConfig"); + try { + FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); + logger.log(Level.INFO, NbBundle.getMessage(HashLookupSettings.class, + "HashDbManager.savedBackupOfOldConfigMsg", + baseMessage, backupFilePath)); + if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, "HashDbManager.savedBackupOfOldConfigMsg", baseMessage, backupFilePath), messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); - } catch (IOException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS - JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); } - HashLookupSettings settings; - settings = new HashLookupSettings(hashDbInfoList); - HashLookupSettings.writeSettings(settings); + } catch (IOException ex) { + logger.log(Level.WARNING, "Failed to save backup of old format configuration file to " + backupFilePath, ex); //NON-NLS + JOptionPane.showMessageDialog(null, baseMessage, messageBoxTitle, JOptionPane.INFORMATION_MESSAGE); } - return new HashLookupSettings(hashDbInfoList); - } else { - return null; + HashLookupSettings settings; + settings = new HashLookupSettings(hashDbInfoList); + HashLookupSettings.writeSettings(settings); } + return new HashLookupSettings(hashDbInfoList); + } else { + return new HashLookupSettings(new ArrayList<>()); } } + /** + * Writes the given settings objects to the disk at the designated location + * + * @param settings The settings to be written + * + * @return Whether or not the settings were written successfully + */ static boolean writeSettings(HashLookupSettings settings) { try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(SERIALIZATION_FILE_PATH))) { out.writeObject(settings); return true; } catch (Exception ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not wtite hash database settings."); + logger.log(Level.SEVERE, "Could not wtite hash database settings."); return false; } } + /** + * Represents the serializable information within a hash lookup in order to + * be written to disk. Used to hand off information when loading and saving + * hash lookups. + */ static final class HashDbInfo implements Serializable { - + private static final long serialVersionUID = 1L; private final String hashSetName; private final HashDbManager.HashDb.KnownFilesType knownFilesType; private final boolean searchDuringIngest; private final boolean sendIngestMessages; private final String path; - + HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) { this.hashSetName = hashSetName; this.knownFilesType = knownFilesType; @@ -279,35 +301,45 @@ class HashLookupSettings implements Serializable { } /** - * @return the hashSetName + * Gets the hash set name. + * + * @return The hash set name. */ String getHashSetName() { return hashSetName; } /** - * @return the knownFilesType + * Gets the known files type setting. + * + * @return The known files type setting. */ HashDbManager.HashDb.KnownFilesType getKnownFilesType() { return knownFilesType; } /** - * @return the searchDuringIngest + * Gets the search during ingest setting. + * + * @return The search during ingest setting. */ boolean getSearchDuringIngest() { return searchDuringIngest; } /** - * @return the sendIngestMessages + * Gets the send ingest messages setting. + * + * @return The send ingest messages setting. */ boolean getSendIngestMessages() { return sendIngestMessages; } /** - * @return the path + * Gets the path. + * + * @return The path. */ String getPath() { return path; @@ -320,13 +352,13 @@ class HashLookupSettings implements Serializable { * clients of the user-defined file types manager. */ static class HashLookupSettingsException extends Exception { - + private static final long serialVersionUID = 1L; - + HashLookupSettingsException(String message) { super(message); } - + HashLookupSettingsException(String message, Throwable throwable) { super(message, throwable); } From 69890a75cba5d0d4dcdda593ebb380d5a7d330d9 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 12 Apr 2016 08:45:06 -0400 Subject: [PATCH 23/29] Semantics changes to HashDbManager. --- .../modules/hashdatabase/HashDbManager.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index e3bd862bb1..e51b840628 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -19,37 +19,36 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Set; -import javax.swing.JFileChooser; -import javax.swing.filechooser.FileNameExtensionFilter; -import org.openide.util.NbBundle; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.logging.Level; +import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.SwingWorker; +import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.commons.io.FilenameUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.HashHitInfo; -import org.sleuthkit.datamodel.HashEntry; -import org.sleuthkit.datamodel.SleuthkitJNI; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; - import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupSettings.HashDbInfo; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.HashEntry; +import org.sleuthkit.datamodel.HashHitInfo; +import org.sleuthkit.datamodel.SleuthkitJNI; +import org.sleuthkit.datamodel.TskCoreException; /** * This class implements a singleton that manages the set of hash databases used @@ -505,14 +504,14 @@ public class HashDbManager implements PropertyChangeListener { this.configureSettings(settings); } } catch (HashLookupSettings.HashLookupSettingsException ex) { - Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Could not read Hash lookup settings from disk.", ex); + Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read Hash lookup settings from disk.", ex); } } @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}", "HashDbManager.noOverwrite.message=Could not overwrite hash database settings."}) private void configureSettings(HashLookupSettings settings) { - boolean missedPath = false; + boolean dbInfoRemoved = false; List hashDbInfoList = settings.getHashDbInfo(); for (HashDbInfo hashDb : hashDbInfoList) { try { @@ -521,7 +520,7 @@ public class HashDbManager implements PropertyChangeListener { addExistingHashDatabaseInternal(hashDb.getHashSetName(), getValidFilePath(hashDb.getHashSetName(), hashDb.getPath()), hashDb.getSearchDuringIngest(), hashDb.getSendIngestMessages(), hashDb.getKnownFilesType()); } else { logger.log(Level.WARNING, Bundle.HashDbManager_noDbPath_message(hashDb.getHashSetName())); - missedPath = true; + dbInfoRemoved = true; } } catch (HashDbManagerException | TskCoreException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex); //NON-NLS @@ -530,14 +529,14 @@ public class HashDbManager implements PropertyChangeListener { "HashDbManager.unableToOpenHashDbMsg", hashDb.getHashSetName()), NbBundle.getMessage(this.getClass(), "HashDbManager.openHashDbErr"), JOptionPane.ERROR_MESSAGE); - missedPath = true; + dbInfoRemoved = true; } } - if (missedPath) { + if (dbInfoRemoved) { try { HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets)); } catch (HashLookupSettings.HashLookupSettingsException ex) { - logger.log(Level.WARNING, Bundle.HashDbManager_noOverwrite_message()); + logger.log(Level.SEVERE, "Could not overwrite hash database settings."); } } } @@ -602,7 +601,7 @@ public class HashDbManager implements PropertyChangeListener { KNOWN(NbBundle.getMessage(HashDbManager.class, "HashDbManager.known.text")), KNOWN_BAD(NbBundle.getMessage(HashDbManager.class, "HashDbManager.knownBad.text")); - private String displayName; + private final String displayName; private KnownFilesType(String displayName) { this.displayName = displayName; From aa4736fafa1435530bef24a5b1a2f82478f6290c Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 12 Apr 2016 16:34:59 -0400 Subject: [PATCH 24/29] Fixed semantics, added documentation.: --- .../modules/hashdatabase/HashDbManager.java | 9 +- .../hashdatabase/HashLookupSettings.java | 126 ++++++++++++------ 2 files changed, 86 insertions(+), 49 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index e51b840628..1aa1353a1d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -500,16 +500,13 @@ public class HashDbManager implements PropertyChangeListener { private void loadHashsetsConfiguration() { try { HashLookupSettings settings = HashLookupSettings.readSettings(); - if (settings != null) { - this.configureSettings(settings); - } + this.configureSettings(settings); } catch (HashLookupSettings.HashLookupSettingsException ex) { Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Could not read Hash lookup settings from disk.", ex); } } - @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}", - "HashDbManager.noOverwrite.message=Could not overwrite hash database settings."}) + @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}"}) private void configureSettings(HashLookupSettings settings) { boolean dbInfoRemoved = false; List hashDbInfoList = settings.getHashDbInfo(); @@ -536,7 +533,7 @@ public class HashDbManager implements PropertyChangeListener { try { HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets)); } catch (HashLookupSettings.HashLookupSettingsException ex) { - logger.log(Level.SEVERE, "Could not overwrite hash database settings."); + logger.log(Level.SEVERE, "Could not overwrite hash database settings.", ex); } } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index 8107add374..b391e4ce98 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -44,7 +44,7 @@ import org.w3c.dom.NodeList; * Class to represent the settings to be serialized for hash lookup. */ final class HashLookupSettings implements Serializable { - + private static final String SERIALIZATION_FILE_NAME = "hashLookup.settings"; //NON-NLS private static final String SERIALIZATION_FILE_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + SERIALIZATION_FILE_NAME; //NON-NLS private static final String SET_ELEMENT = "hash_set"; //NON-NLS @@ -57,10 +57,15 @@ final class HashLookupSettings implements Serializable { private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME; private static final Logger logger = Logger.getLogger(HashDbManager.class.getName()); - + private static final long serialVersionUID = 1L; private final List hashDbInfoList; - + + /** + * Constructs a settings object to be serialized for hash lookups + * + * @param hashDbInfoList The list of hash db info. + */ HashLookupSettings(List hashDbInfoList) { this.hashDbInfoList = hashDbInfoList; } @@ -68,15 +73,22 @@ final class HashLookupSettings implements Serializable { /** * Constructs a settings object to be serialized for hash lookups * - * @param knownHashSets - * @param knownBadHashSets + * @param knownHashSets The list known hash sets for the settings. + * @param knownBadHashSets The list of known bad hash sets for the settings. */ HashLookupSettings(List knownHashSets, List knownBadHashSets) throws HashLookupSettingsException { hashDbInfoList = new ArrayList<>(); this.addHashesToList(knownHashSets); this.addHashesToList(knownBadHashSets); } - + + /** + * Adds each HashDb to the settings. + * + * @param hashSetList The list of HashDb to add to the settings + * + * @throws * pacannot be obtained + */ private void addHashesToList(List hashSetList) throws HashLookupSettingsException { for (HashDbManager.HashDb hashDb : hashSetList) { try { @@ -96,21 +108,38 @@ final class HashLookupSettings implements Serializable { /** * Gets the list of hash db info that this settings contains * - * @return the hashDbInfoList + * @return The list of hash databse info */ List getHashDbInfo() { return hashDbInfoList; } - + + /** + * Reads the settings from the disk. + * + * @return The settings object representing what was read. + * + * @throws HashLookupSettingsException When there is a problem reading the + * settings. + */ static HashLookupSettings readSettings() throws HashLookupSettingsException { File fileSetFile = new File(SERIALIZATION_FILE_PATH); if (fileSetFile.exists()) { return readSerializedSettings(); } return readXmlSettings(); - + } - + + /** + * Reads the serialization settings from the disk + * + * @return Settings object representing what is saved in the serialization + * file. + * + * @throws HashLookupSettingsException If there's a problem importing the + * settings + */ private static HashLookupSettings readSerializedSettings() throws HashLookupSettingsException { try { try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) { @@ -121,7 +150,16 @@ final class HashLookupSettings implements Serializable { throw new HashLookupSettingsException("Could not read hash database settings.", ex); } } - + + /** + * Reads the xml settings from the disk + * + * @return Settings object representing what is saved in the xml file, or an + * empty settings if there is no xml file. + * + * @throws HashLookupSettingsException If there's a problem importing the + * settings + */ private static HashLookupSettings readXmlSettings() throws HashLookupSettingsException { File xmlFile = new File(configFilePath); if (xmlFile.exists()) { @@ -130,34 +168,30 @@ final class HashLookupSettings implements Serializable { // Open the XML document that implements the configuration file. final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath); if (doc == null) { - return null; + throw new HashLookupSettingsException("Could not open xml document."); } // Get the root element. Element root = doc.getDocumentElement(); if (root == null) { - logger.log(Level.SEVERE, "Error loading hash sets: invalid file format."); //NON-NLS - return null; + throw new HashLookupSettingsException("Error loading hash sets: invalid file format."); } // Get the hash set elements. NodeList setsNList = root.getElementsByTagName(SET_ELEMENT); int numSets = setsNList.getLength(); - if (numSets == 0) { - logger.log(Level.WARNING, "No element hash_set exists."); //NON-NLS - } // Create HashDbInfo objects for each hash set element. Throws on malformed xml. - String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS - String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class"; //NON-NLS + String attributeErrorMessage = "Missing %s attribute"; //NON-NLS + String elementErrorMessage = "Empty %s element"; //NON-NLS List hashSetNames = new ArrayList<>(); List hashDbInfoList = new ArrayList<>(); for (int i = 0; i < numSets; ++i) { Element setEl = (Element) setsNList.item(i); - + String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE); if (hashSetName.isEmpty()) { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(attributeErrorMessage, SET_NAME_ATTRIBUTE)); } // Handle configurations saved before duplicate hash set names were not permitted. @@ -168,9 +202,7 @@ final class HashLookupSettings implements Serializable { ++suffix; newHashSetName = hashSetName + suffix; } while (hashSetNames.contains(newHashSetName)); - logger.log(Level.INFO, NbBundle.getMessage(HashLookupSettings.class, - "HashDbManager.replacingDuplicateHashsetNameMsg", - hashSetName, newHashSetName)); + logger.log(Level.INFO, "Duplicate hash set name " + hashSetName + " found.\nReplacing with " + newHashSetName + "."); if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, @@ -181,10 +213,10 @@ final class HashLookupSettings implements Serializable { hashSetName = newHashSetName; } } - + String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE); if (knownFilesType.isEmpty()) { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(attributeErrorMessage, SET_TYPE_ATTRIBUTE)); } // Handle legacy known files types. @@ -192,19 +224,19 @@ final class HashLookupSettings implements Serializable { knownFilesType = HashDbManager.HashDb.KnownFilesType.KNOWN.toString(); updatedSchema = true; } - + final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE); if (searchDuringIngest.isEmpty()) { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(attributeErrorMessage, SEND_INGEST_MESSAGES_ATTRIBUTE)); } Boolean searchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest); - + final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE); if (searchDuringIngest.isEmpty()) { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(attributeErrorMessage, SEND_INGEST_MESSAGES_ATTRIBUTE)); } Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages); - + String dbPath; NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT); if (pathsNList.getLength() > 0) { @@ -215,19 +247,19 @@ final class HashLookupSettings implements Serializable { if (null != legacyPathNumber && !legacyPathNumber.isEmpty()) { updatedSchema = true; } - + dbPath = pathEl.getTextContent(); if (dbPath.isEmpty()) { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(elementErrorMessage, PATH_ELEMENT)); } } else { - throw new HashLookupSettingsException(SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage); + throw new HashLookupSettingsException(String.format(elementErrorMessage, PATH_ELEMENT)); } hashDbInfoList.add(new HashDbInfo(hashSetName, HashDbManager.HashDb.KnownFilesType.valueOf(knownFilesType), searchDuringIngestFlag, sendIngestMessagesFlag, dbPath)); hashSetNames.add(hashSetName); } - + if (updatedSchema) { String backupFilePath = configFilePath + ".v1_backup"; //NON-NLS String messageBoxTitle = NbBundle.getMessage(HashLookupSettings.class, @@ -236,9 +268,7 @@ final class HashLookupSettings implements Serializable { "HashDbManager.baseMessage.updatedFormatHashDbConfig"); try { FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); - logger.log(Level.INFO, NbBundle.getMessage(HashLookupSettings.class, - "HashDbManager.savedBackupOfOldConfigMsg", - baseMessage, backupFilePath)); + logger.log(Level.INFO, baseMessage + "\nA backup copy of the old configuration has been saved as\n" + backupFilePath); if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, @@ -284,14 +314,24 @@ final class HashLookupSettings implements Serializable { * hash lookups. */ static final class HashDbInfo implements Serializable { - + private static final long serialVersionUID = 1L; private final String hashSetName; private final HashDbManager.HashDb.KnownFilesType knownFilesType; private final boolean searchDuringIngest; private final boolean sendIngestMessages; private final String path; - + + /** + * Constructs a HashDbInfo object + * + * @param hashSetName The name of the hash set + * @param knownFilesType The known files type + * @param searchDuringIngest Whether or not the db is searched during + * ingest + * @param sendIngestMessages Whether or not ingest messages are sent + * @param path The path to the db + */ HashDbInfo(String hashSetName, HashDbManager.HashDb.KnownFilesType knownFilesType, boolean searchDuringIngest, boolean sendIngestMessages, String path) { this.hashSetName = hashSetName; this.knownFilesType = knownFilesType; @@ -352,13 +392,13 @@ final class HashLookupSettings implements Serializable { * clients of the user-defined file types manager. */ static class HashLookupSettingsException extends Exception { - + private static final long serialVersionUID = 1L; - + HashLookupSettingsException(String message) { super(message); } - + HashLookupSettingsException(String message, Throwable throwable) { super(message, throwable); } From 8c438df2c10fa4869f6d76c3670e95126cf17dfe Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 13 Apr 2016 11:15:40 -0400 Subject: [PATCH 25/29] Added documentation and fixed log messages. --- .../autopsy/modules/hashdatabase/HashDbManager.java | 6 ++++++ .../autopsy/modules/hashdatabase/HashLookupSettings.java | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 1aa1353a1d..d12be8d8a6 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -506,6 +506,12 @@ public class HashDbManager implements PropertyChangeListener { } } + /** + * Configures the given settings object by adding all contained hash db to + * the system. + * + * @param settings The settings to configure. + */ @Messages({"# {0} - database name", "HashDbManager.noDbPath.message=Couldn't get valid database path for: {0}"}) private void configureSettings(HashLookupSettings settings) { boolean dbInfoRemoved = false; diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java index b391e4ce98..ae52f86219 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettings.java @@ -202,7 +202,7 @@ final class HashLookupSettings implements Serializable { ++suffix; newHashSetName = hashSetName + suffix; } while (hashSetNames.contains(newHashSetName)); - logger.log(Level.INFO, "Duplicate hash set name " + hashSetName + " found.\nReplacing with " + newHashSetName + "."); + logger.log(Level.INFO, "Duplicate hash set name " + hashSetName + " found. Replacing with " + newHashSetName + "."); if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, @@ -268,7 +268,7 @@ final class HashLookupSettings implements Serializable { "HashDbManager.baseMessage.updatedFormatHashDbConfig"); try { FileUtils.copyFile(new File(configFilePath), new File(backupFilePath)); - logger.log(Level.INFO, baseMessage + "\nA backup copy of the old configuration has been saved as\n" + backupFilePath); + logger.log(Level.INFO, "Updated the schema, backup saved at: " + backupFilePath); if (RuntimeProperties.coreComponentsAreActive()) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(HashLookupSettings.class, From 53453fe8ee81e47437c73f90f7c6168aee4c86cb Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 13 Apr 2016 12:59:27 -0400 Subject: [PATCH 26/29] Updated documentation, slight semantics changes. --- .../AddFileTypeSignatureDialog.java | 57 +++++++------- .../filetypeid/AddFileTypeSignaturePanel.java | 51 ++++++++---- .../autopsy/modules/filetypeid/FileType.java | 30 ++++---- .../FileTypeIdGlobalSettingsPanel.java | 6 +- .../UserDefinedFileTypesManager.java | 77 +++++++++---------- 5 files changed, 122 insertions(+), 99 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index 33304a8438..3365d33eb3 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -25,10 +25,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.ArrayList; -import java.util.List; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; @@ -40,10 +36,8 @@ import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; /** - * - * A dialog box that allows a user to configure and execute analysis of one or - * more data sources with ingest modules or analysis of the contents of a - * directory with file-level ingest modules. + * A dialog box that allows a user to create a file type signature, to be added + * to a selected file type. */ final class AddFileTypeSignatureDialog extends JDialog { @@ -54,21 +48,16 @@ final class AddFileTypeSignatureDialog extends JDialog { private BUTTON_PRESSED result; /** - * @return the signature + * Enum used for letting creator of this dialog know whether or not OK was + * pressed. */ - public Signature getSignature() { - return signature; - } - enum BUTTON_PRESSED { - ADD, CANCEL; + OK, CANCEL; } /** - * Constructs a dialog box that allows a user to configure and execute - * analysis of the contents of a directory with file-level ingest modules. - * + * Creates a file type signature dialog for a new signature. */ AddFileTypeSignatureDialog() { super(new JFrame(TITLE), TITLE, true); @@ -76,6 +65,11 @@ final class AddFileTypeSignatureDialog extends JDialog { this.display(true); } + /** + * Creates a file type signature dialog for a signature being edited. + * + * @param toEdit The signature to edit. + */ AddFileTypeSignatureDialog(Signature toEdit) { super(new JFrame(TITLE), TITLE, true); this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(toEdit); @@ -83,14 +77,27 @@ final class AddFileTypeSignatureDialog extends JDialog { } /** - * @return the result + * Gets the signature that was created by this dialog. + * + * @return the signature. + */ + public Signature getSignature() { + return signature; + } + + /** + * Gets which button was pressed (OK or Cancel). + * + * @return The result. */ public BUTTON_PRESSED getResult() { return result; } /** - * Displays this dialog. + * Displays the add signature dialog. + * + * @param add Whether or not this is an edit or a new window. */ @Messages({ "AddFileTypeSignatureDialog.addButton.title=Add", @@ -117,8 +124,7 @@ final class AddFileTypeSignatureDialog extends JDialog { JButton addButton; if (add) { addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title()); - } - else { + } else { addButton = new JButton(Bundle.AddFileTypeSignatureDialog_addButton_title2()); } addButton.addActionListener(new ActionListener() { @@ -166,11 +172,10 @@ final class AddFileTypeSignatureDialog extends JDialog { } /** - * Saves the ingest job settings, optionally starts an ingest job for each - * data source, then closes the dialog + * Performs actions on the fields based on whether the ok button was pressed + * or not. * - * @param okPressed True if ingest job(s) should be started, false - * otherwise. + * @param okPressed Whether ok was pressed. */ @Messages({"AddFileTypeSignatureDialog.invalidSignature.message=Invalid signature"}) private void doButtonAction(boolean okPressed) { @@ -178,7 +183,7 @@ final class AddFileTypeSignatureDialog extends JDialog { Signature sig = addFileTypeSigPanel.getSignature(); if (sig != null) { this.signature = sig; - this.result = BUTTON_PRESSED.ADD; + this.result = BUTTON_PRESSED.OK; setVisible(false); } } else { diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java index 65afa26ff9..98d8d5e963 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -1,29 +1,34 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2016 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.modules.filetypeid; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; import javax.swing.JOptionPane; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import javax.xml.bind.DatatypeConverter; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; /** - * - * @author oliver + * Panel for creating a file type signature to be added to a file type. */ class AddFileTypeSignaturePanel extends javax.swing.JPanel { @@ -33,21 +38,25 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem"); /** - * Creates new form AddFileTypeSignaturePanel + * Creates a panel for a new signature. */ AddFileTypeSignaturePanel() { initComponents(); customizeComponents(); } + /** + * Creates a panel for a signature being edited. + * + * @param toEdit The signature to edit. + */ AddFileTypeSignaturePanel(Signature toEdit) { this(); this.setComponentValues(toEdit); } /** - * Does child component initialization in addition to that done by the - * Matisse generated code. + * Configures the components of the panel correctly. */ private void customizeComponents() { setSignatureTypeComboBoxModel(); @@ -76,6 +85,11 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { offsetRelativeToComboBox.setSelectedItem(START_OFFSET_RELATIVE_COMBO_BOX_ITEM); } + /** + * Sets the values for the components based on the signature being edited. + * + * @param toEdit The signature information to implement. + */ @Messages({"AddFileTypeSignaturePanel.signatureStringFail.text=Couldn't get signatures string"}) private void setComponentValues(Signature toEdit) { if (toEdit.isRelativeToStart()) { @@ -100,6 +114,13 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { } } + /** + * Gets the file type signature for this panel, pops up error windows if the + * signature is incomplete. + * + * @return The signature of this panel, or null if it is an invalid + * signature. + */ public Signature getSignature() { /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index 427d08e212..d645c1c4d5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -23,18 +23,18 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.xml.bind.DatatypeConverter; -import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** - * Represents a file type characterized by a file signatures. + * Represents a file type characterized by file signatures. *

* Thread-safe (immutable). */ @@ -47,11 +47,11 @@ class FileType implements Serializable { private final boolean alert; /** - * Creates a representation of a file type characterized by a file + * Creates a representation of a file type characterized by file * signatures. * * @param mimeType The mime type to associate with this file type. - * @param signature The signatures that characterizes this file type. + * @param signatures The signatures that characterize this file type. * @param filesSetName The name of an interesting files set that includes * files of this type, may be the empty string. * @param alert Whether the user wishes to be alerted when a file @@ -79,7 +79,7 @@ class FileType implements Serializable { * @return The signatures. */ List getSignatures() { - return this.signatures; + return Collections.unmodifiableList(this.signatures); } void addSignature(Signature sig) { @@ -147,7 +147,7 @@ class FileType implements Serializable { } /** - * A file signatures consisting of a sequence of bytes at a specific offset + * A file signature consisting of a sequence of bytes at a specific offset * within a file. *

* Thread-safe (immutable). @@ -158,7 +158,7 @@ class FileType implements Serializable { private static final Logger logger = Logger.getLogger(Signature.class.getName()); /** - * The way the signatures byte sequence should be interpreted. + * The way the signature byte sequence should be interpreted. */ enum Type { @@ -171,7 +171,7 @@ class FileType implements Serializable { private final boolean isRelativeToStart; /** - * Creates a file signatures consisting of a sequence of bytes at a + * Creates a file signature consisting of a sequence of bytes at a * specific offset within a file. * * @param signatureBytes The signature bytes. @@ -217,7 +217,7 @@ class FileType implements Serializable { } /** - * Creates a file signatures consisting of a sequence of bytes at a + * Creates a file signature consisting of a sequence of bytes at a * specific offset within a file. * * @param signatureBytes The signature bytes. @@ -269,7 +269,7 @@ class FileType implements Serializable { } /** - * Gets the byte sequence of the signatures. + * Gets the byte sequence of the signature. * * @return The byte sequence as an array of bytes. */ @@ -278,7 +278,7 @@ class FileType implements Serializable { } /** - * Gets the offset of the signatures. + * Gets the offset of the signature. * * @return The offset. */ @@ -287,9 +287,9 @@ class FileType implements Serializable { } /** - * Gets the interpretation of the byte sequence for the signatures. + * Gets the interpretation of the byte sequence for the signature. * - * @return The signatures type. + * @return The signature type. */ Type getType() { return type; @@ -300,7 +300,7 @@ class FileType implements Serializable { } /** - * Determines whether or not the signatures is contained within a given + * Determines whether or not the signature is contained within a given * file. * * @param file The file to test @@ -316,7 +316,7 @@ class FileType implements Serializable { actualOffset = file.getSize() - 1 - offset; } if (file.getSize() < (actualOffset + signatureBytes.length)) { - return false; /// too small, can't contain this signatures + return false; /// too small, can't contain this signature } try { byte[] buffer = new byte[signatureBytes.length]; diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 6e42f7d7fa..b572fbed30 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -26,9 +26,7 @@ import java.util.Collections; import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; -import javax.swing.JList; import javax.swing.JOptionPane; -import javax.swing.ListCellRenderer; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -616,7 +614,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed if (evt.getSource().equals(this.addSigButton)) { this.addSigDialog = new AddFileTypeSignatureDialog(); - if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { + if (addSigDialog.getResult() == BUTTON_PRESSED.OK) { signaturesListModel.addElement(this.addSigDialog.getSignature()); } } @@ -634,7 +632,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private void editSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSigButtonActionPerformed if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) { this.addSigDialog = new AddFileTypeSignatureDialog(this.signatureList.getSelectedValue()); - if (addSigDialog.getResult() == BUTTON_PRESSED.ADD) { + if (addSigDialog.getResult() == BUTTON_PRESSED.OK) { signaturesListModel.removeElementAt(this.signatureList.getSelectedIndex()); this.signaturesListModel.addElement(this.addSigDialog.getSignature()); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index 6efc662eb0..a2ee541f43 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -27,10 +27,8 @@ import java.io.UnsupportedEncodingException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.logging.Level; -import javax.persistence.PersistenceException; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -44,7 +42,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; -import org.sleuthkit.datamodel.TskCoreException; import org.w3c.dom.Node; import org.xml.sax.SAXException; @@ -192,118 +189,118 @@ final class UserDefinedFileTypesManager { List signatureList; signatureList = new ArrayList<>(); signatureList.add(new Signature("(signatureList), "", false); //NON-NLS + fileType = new FileType("text/xml", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for gzip byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS signatureList = new ArrayList<>(); signatureList.add(new Signature(byteArray, 0L)); - fileType = new FileType("application/x-gzip", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("application/x-gzip", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .wk1 byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 0L)); - fileType = new FileType("application/x-123", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("application/x-123", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for Radiance image byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 0L)); - fileType = new FileType("image/vnd.radiance", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/vnd.radiance", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .dcx image byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 0L)); - fileType = new FileType("image/x-dcx", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-dcx", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .ics image - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("icns", 0L)); - fileType = new FileType("image/x-icns", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-icns", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pict image byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 522L)); - fileType = new FileType("image/x-pict", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-pict", signatureList, "", false); //NON-NLS fileTypes.add(fileType); byteArray = DatatypeConverter.parseHexBinary("1100"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 522L)); - fileType = new FileType("image/x-pict", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-pict", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pam - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("P7", 0L)); - fileType = new FileType("image/x-portable-arbitrarymap", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-portable-arbitrarymap", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .pfm - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("PF", 0L)); - fileType = new FileType("image/x-portable-floatmap", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-portable-floatmap", signatureList, "", false); //NON-NLS fileTypes.add(fileType); - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("Pf", 0L)); - fileType = new FileType("image/x-portable-floatmap", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-portable-floatmap", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .tga byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 17, false)); - fileType = new FileType("image/x-tga", new ArrayList<>(signatureList), "", false); //NON-NLS + fileType = new FileType("image/x-tga", signatureList, "", false); //NON-NLS fileTypes.add(fileType); // Add rule for .ilbm - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); signatureList.add(new Signature("ILBM", 8L)); - fileType = new FileType("image/x-ilbm", new ArrayList<>(signatureList), "", false); + fileType = new FileType("image/x-ilbm", signatureList, "", false); fileTypes.add(fileType); - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); signatureList.add(new Signature("PBM", 8L)); - fileType = new FileType("image/x-ilbm", new ArrayList<>(signatureList), "", false); + fileType = new FileType("image/x-ilbm", signatureList, "", false); fileTypes.add(fileType); // Add rule for .webp - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("RIFF", 0L)); signatureList.add(new Signature("WEBP", 8L)); - fileType = new FileType("image/webp", new ArrayList<>(signatureList), "", false); + fileType = new FileType("image/webp", signatureList, "", false); fileTypes.add(fileType); // Add rule for .aiff - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); signatureList.add(new Signature("AIFF", 8L)); - fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileType = new FileType("audio/aiff", signatureList, "", false); fileTypes.add(fileType); - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); signatureList.add(new Signature("AIFC", 8L)); - fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileType = new FileType("audio/aiff", signatureList, "", false); fileTypes.add(fileType); - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); signatureList.add(new Signature("8SVX", 8L)); - fileType = new FileType("audio/aiff", new ArrayList<>(signatureList), "", false); + fileType = new FileType("audio/aiff", signatureList, "", false); fileTypes.add(fileType); // Add .iff - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); - fileType = new FileType("application/x-iff", new ArrayList<>(signatureList), "", false); + fileType = new FileType("application/x-iff", signatureList, "", false); fileTypes.add(fileType); } // parseHexBinary() throws this if the argument passed in is not Hex @@ -477,6 +474,8 @@ final class UserDefinedFileTypesManager { Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem); String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem); boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem); + // File type definitions in the XML file were written prior to the + // implementation of multiple signatures per type. List sigList = new ArrayList<>(); sigList.add(signature); return new FileType(mimeType, sigList, filesSetName, alert); From 1e7c545b8d0844f56409d981d4b4f2c717ea77f9 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 13 Apr 2016 13:27:27 -0400 Subject: [PATCH 27/29] Bugfix. --- .../filetypeid/UserDefinedFileTypesManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index a2ee541f43..ff5ed5a8f9 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -29,11 +29,8 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; -import javax.xml.parsers.ParserConfigurationException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; import javax.xml.bind.DatatypeConverter; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.openide.util.NbBundle; import org.openide.util.io.NbObjectInputStream; @@ -42,7 +39,10 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** @@ -194,7 +194,7 @@ final class UserDefinedFileTypesManager { // Add rule for gzip byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS - signatureList = new ArrayList<>(); + signatureList.clear(); signatureList.add(new Signature(byteArray, 0L)); fileType = new FileType("application/x-gzip", signatureList, "", false); //NON-NLS fileTypes.add(fileType); @@ -296,7 +296,7 @@ final class UserDefinedFileTypesManager { signatureList.add(new Signature("8SVX", 8L)); fileType = new FileType("audio/aiff", signatureList, "", false); fileTypes.add(fileType); - + // Add .iff signatureList.clear(); signatureList.add(new Signature("FORM", 0L)); From 199bc555feb80f8c6197becb52deb62b88c44249 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 13 Apr 2016 17:19:50 -0400 Subject: [PATCH 28/29] Fix typo in NEWS.txt --- NEWS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.txt b/NEWS.txt index a4aece14bd..4335d9686a 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -3,7 +3,7 @@ Improvements: - VMWare virtual machine files (vmdk) and Microsoft Virtual Hard Drives (vhd) can be added as data sources. - New core ingest module detects vmdk and vhd files embedded in other data sources and adds them as data sources. - Text associated with artifacts posted to the blackboard is indexed and searched for keywords. -- Custom (user-defined) blackboard artifact and attribute types displayed in UI and included reports. +- Custom (user-defined) blackboard artifact and attribute types displayed in UI and included in reports. - File size and MIME type conditions can be specified for interesting files rules. - File size and MIME type conditions can be specified for file search by attributes. - Local/GMT time preference is used in reports. From 6419db50b5c414eb8ccbda714c3c352d88edf3a4 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Thu, 14 Apr 2016 11:29:13 -0400 Subject: [PATCH 29/29] Fixed form issues, spelling error. --- .../modules/filetypeid/Bundle.properties | 2 +- .../FileTypeIdGlobalSettingsPanel.form | 274 ++++++------------ .../FileTypeIdGlobalSettingsPanel.java | 4 +- 3 files changed, 85 insertions(+), 195 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties index b53027b29d..d99cf4e0ac 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties @@ -49,6 +49,6 @@ AddFileTypeSignaturePanel.signatureLabel.text=Signature AddFileTypeSignaturePanel.hexPrefixLabel.text=0x AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetTextField.text= +FileTypeIdGlobalSettingsPanel.deleteSigButton.text=Delete Signature FileTypeIdGlobalSettingsPanel.addSigButton.text=Add Signature FileTypeIdGlobalSettingsPanel.editSigButton.text=Edit Signature -FileTypeIdGlobalSettingsPanel.deleteSigButton.text=Delete Signatrue diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form index 828b7b3222..0ac796f92c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form @@ -3,10 +3,10 @@

- + - + @@ -33,69 +33,46 @@ - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - @@ -115,7 +92,7 @@ - + @@ -134,29 +111,14 @@ - - - - - - - - - - - - + - - - + + + + - - - - - @@ -165,7 +127,6 @@ - @@ -232,57 +193,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -328,48 +238,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -448,32 +316,54 @@ - - - - - - - - - - - + - + - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index b572fbed30..a2adf4e12a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -344,7 +344,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane private void initComponents() { typesScrollPane = new javax.swing.JScrollPane(); - typesList = new javax.swing.JList(); + typesList = new javax.swing.JList<>(); separator = new javax.swing.JSeparator(); mimeTypeLabel = new javax.swing.JLabel(); mimeTypeTextField = new javax.swing.JTextField(); @@ -358,7 +358,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); - signatureList = new javax.swing.JList(); + signatureList = new javax.swing.JList<>(); addSigButton = new javax.swing.JButton(); editSigButton = new javax.swing.JButton(); deleteSigButton = new javax.swing.JButton();