diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java index d32234fa92..d3258e5885 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java @@ -208,11 +208,11 @@ public class PlatformUtil { * @throws IOException exception thrown if extract the file failed for IO * reasons */ - public static boolean extractResourceToUserConfigDir(final Class resourceClass, final String resourceFile) throws IOException { + public static boolean extractResourceToUserConfigDir(final Class resourceClass, final String resourceFile, boolean overWrite) throws IOException { final File userDir = new File(getUserConfigDirectory()); final File resourceFileF = new File(userDir + File.separator + resourceFile); - if (resourceFileF.exists()) { + if (resourceFileF.exists() && !overWrite) { return false; } diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java index 2a19075913..ed401bc5c3 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java @@ -70,7 +70,7 @@ public class XMLUtil { */ public static boolean xmlIsValid(DOMSource xmlfile, Class clazz, String schemaFile) { try{ - PlatformUtil.extractResourceToUserConfigDir(clazz, schemaFile); + PlatformUtil.extractResourceToUserConfigDir(clazz, schemaFile, false); File schemaLoc = new File(PlatformUtil.getUserConfigDirectory() + File.separator + schemaFile); SchemaFactory schm = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); try{ diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestPipelinesConfiguration.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestPipelinesConfiguration.java index 5c93b9d102..7ac7e4f238 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestPipelinesConfiguration.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestPipelinesConfiguration.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.w3c.dom.Document; @@ -39,12 +40,15 @@ import org.w3c.dom.NodeList; final class IngestPipelinesConfiguration { private static final Logger logger = Logger.getLogger(IngestPipelinesConfiguration.class.getName()); - private final static String PIPELINES_CONFIG_FILE = "pipeline_config.xml"; - private final static String PIPELINES_CONFIG_FILE_XSD = "PipelineConfigSchema.xsd"; + private static final String PIPELINE_CONFIG_FILE_VERSION_KEY = "PipelineConfigFileVersion"; + private static final String PIPELINE_CONFIG_FILE_VERSION_NO_STRING = "1"; + private static final int PIPELINE_CONFIG_FILE_VERSION_NO = 1; + private static final String PIPELINES_CONFIG_FILE = "pipeline_config.xml"; + private static final String PIPELINES_CONFIG_FILE_XSD = "PipelineConfigSchema.xsd"; private static final String XML_PIPELINE_ELEM = "PIPELINE"; private static final String XML_PIPELINE_TYPE_ATTR = "type"; - private final static String DATA_SOURCE_INGEST_PIPELINE_TYPE = "ImageAnalysis"; - private final static String FILE_INGEST_PIPELINE_TYPE = "FileAnalysis"; + private static final String DATA_SOURCE_INGEST_PIPELINE_TYPE = "ImageAnalysis"; + private static final String FILE_INGEST_PIPELINE_TYPE = "FileAnalysis"; private static final String XML_MODULE_ELEM = "MODULE"; private static final String XML_MODULE_CLASS_NAME_ATTR = "location"; private static IngestPipelinesConfiguration instance; @@ -73,65 +77,77 @@ final class IngestPipelinesConfiguration { private void readPipelinesConfigurationFile() { try { - PlatformUtil.extractResourceToUserConfigDir(IngestPipelinesConfiguration.class, PIPELINES_CONFIG_FILE); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error copying default pipeline configuration to user dir", ex); - return; - } - - String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + PIPELINES_CONFIG_FILE; - Document doc = XMLUtil.loadDoc(IngestPipelinesConfiguration.class, configFilePath, PIPELINES_CONFIG_FILE_XSD); - if (doc == null) { - return; - } - - Element rootElement = doc.getDocumentElement(); - if (rootElement == null) { - logger.log(Level.SEVERE, "Invalid pipelines config file"); - return; - } - - NodeList pipelineElements = rootElement.getElementsByTagName(XML_PIPELINE_ELEM); - int numPipelines = pipelineElements.getLength(); - if (numPipelines < 1 || numPipelines > 2) { - logger.log(Level.SEVERE, "Invalid pipelines config file"); - return; - } - - List pipelineConfig = null; - for (int pipelineNum = 0; pipelineNum < numPipelines; ++pipelineNum) { - Element pipelineElement = (Element) pipelineElements.item(pipelineNum); - String pipelineTypeAttr = pipelineElement.getAttribute(XML_PIPELINE_TYPE_ATTR); - if (pipelineTypeAttr != null) { - switch (pipelineTypeAttr) { - case DATA_SOURCE_INGEST_PIPELINE_TYPE: - pipelineConfig = dataSourceIngestPipelineConfig; - break; - case FILE_INGEST_PIPELINE_TYPE: - pipelineConfig = fileIngestPipelineConfig; - break; - default: - logger.log(Level.SEVERE, "Invalid pipelines config file"); - return; - } + boolean overWrite; + if (!ModuleSettings.settingExists(this.getClass().getSimpleName(), PIPELINE_CONFIG_FILE_VERSION_KEY)) { + ModuleSettings.setConfigSetting(this.getClass().getSimpleName(), PIPELINE_CONFIG_FILE_VERSION_KEY, PIPELINE_CONFIG_FILE_VERSION_NO_STRING); + overWrite = true; + } else { + int versionNumber = Integer.parseInt(ModuleSettings.getConfigSetting(this.getClass().getSimpleName(), PIPELINE_CONFIG_FILE_VERSION_KEY)); + overWrite = versionNumber < PIPELINE_CONFIG_FILE_VERSION_NO; + // TODO: Migrate user edits } - // Create an ordered list of class names. The sequence of class - // names defines the sequence of modules in the pipeline. - if (pipelineConfig != null) { - NodeList modulesElems = pipelineElement.getElementsByTagName(XML_MODULE_ELEM); - int numModules = modulesElems.getLength(); - if (numModules == 0) { - break; + boolean fileCopied = PlatformUtil.extractResourceToUserConfigDir(IngestPipelinesConfiguration.class, PIPELINES_CONFIG_FILE, overWrite); + if (!fileCopied) { + logger.log(Level.SEVERE, "Failure copying default pipeline configuration to user dir"); + } + + String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + PIPELINES_CONFIG_FILE; + Document doc = XMLUtil.loadDoc(IngestPipelinesConfiguration.class, configFilePath, PIPELINES_CONFIG_FILE_XSD); + if (doc == null) { + return; + } + + Element rootElement = doc.getDocumentElement(); + if (rootElement == null) { + logger.log(Level.SEVERE, "Invalid pipelines config file"); + return; + } + + NodeList pipelineElements = rootElement.getElementsByTagName(XML_PIPELINE_ELEM); + int numPipelines = pipelineElements.getLength(); + if (numPipelines < 1 || numPipelines > 2) { + logger.log(Level.SEVERE, "Invalid pipelines config file"); + return; + } + + List pipelineConfig = null; + for (int pipelineNum = 0; pipelineNum < numPipelines; ++pipelineNum) { + Element pipelineElement = (Element) pipelineElements.item(pipelineNum); + String pipelineTypeAttr = pipelineElement.getAttribute(XML_PIPELINE_TYPE_ATTR); + if (pipelineTypeAttr != null) { + switch (pipelineTypeAttr) { + case DATA_SOURCE_INGEST_PIPELINE_TYPE: + pipelineConfig = dataSourceIngestPipelineConfig; + break; + case FILE_INGEST_PIPELINE_TYPE: + pipelineConfig = fileIngestPipelineConfig; + break; + default: + logger.log(Level.SEVERE, "Invalid pipelines config file"); + return; + } } - for (int moduleNum = 0; moduleNum < numModules; ++moduleNum) { - Element moduleElement = (Element) modulesElems.item(moduleNum); - final String moduleClassName = moduleElement.getAttribute(XML_MODULE_CLASS_NAME_ATTR); - if (moduleClassName != null) { - pipelineConfig.add(moduleClassName); + + // Create an ordered list of class names. The sequence of class + // names defines the sequence of modules in the pipeline. + if (pipelineConfig != null) { + NodeList modulesElems = pipelineElement.getElementsByTagName(XML_MODULE_ELEM); + int numModules = modulesElems.getLength(); + if (numModules == 0) { + break; + } + for (int moduleNum = 0; moduleNum < numModules; ++moduleNum) { + Element moduleElement = (Element) modulesElems.item(moduleNum); + final String moduleClassName = moduleElement.getAttribute(XML_MODULE_CLASS_NAME_ATTR); + if (moduleClassName != null) { + pipelineConfig.add(moduleClassName); + } } } } + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error copying default pipeline configuration to user dir", ex); } } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchXML.java b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchXML.java index 10b3319eb8..d90802a69b 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchXML.java +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchXML.java @@ -61,7 +61,7 @@ class FileExtMismatchXML { this.filePath = filePath; try { - boolean extracted = PlatformUtil.extractResourceToUserConfigDir(FileExtMismatchXML.class, DEFAULT_CONFIG_FILE_NAME); + boolean extracted = PlatformUtil.extractResourceToUserConfigDir(FileExtMismatchXML.class, DEFAULT_CONFIG_FILE_NAME, false); } catch (IOException ex) { logger.log(Level.SEVERE, "Error copying default mismatch configuration to user dir ", ex); } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/SearchEngineURLQueryAnalyzer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/SearchEngineURLQueryAnalyzer.java index b57eb19a66..a175a7d2c4 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/SearchEngineURLQueryAnalyzer.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/SearchEngineURLQueryAnalyzer.java @@ -322,7 +322,7 @@ class SearchEngineURLQueryAnalyzer extends Extract { @Override void init() throws IngestModuleException { try { - PlatformUtil.extractResourceToUserConfigDir(SearchEngineURLQueryAnalyzer.class, XMLFILE); + PlatformUtil.extractResourceToUserConfigDir(SearchEngineURLQueryAnalyzer.class, XMLFILE, false); init2(); } catch (IOException e) { String message = "Unable to find " + XMLFILE; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/UsbDeviceIdMapper.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/UsbDeviceIdMapper.java index 9870b9af1d..b7b8abc56d 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/UsbDeviceIdMapper.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/UsbDeviceIdMapper.java @@ -87,7 +87,7 @@ class UsbDeviceIdMapper { */ private void loadDeviceMap() throws FileNotFoundException, IOException { devices = new HashMap<>(); - PlatformUtil.extractResourceToUserConfigDir(this.getClass(), DataFile); + PlatformUtil.extractResourceToUserConfigDir(this.getClass(), DataFile, false); try (Scanner dat = new Scanner(new FileInputStream(new java.io.File(PlatformUtil.getUserConfigDirectory() + File.separator + "USB_DATA.txt")))) { /* Syntax of file: * diff --git a/ScalpelCarver/src/org/sleuthkit/autopsy/scalpel/ScalpelCarverIngestModule.java b/ScalpelCarver/src/org/sleuthkit/autopsy/scalpel/ScalpelCarverIngestModule.java index 5a0bc208a6..8b2211a36b 100644 --- a/ScalpelCarver/src/org/sleuthkit/autopsy/scalpel/ScalpelCarverIngestModule.java +++ b/ScalpelCarver/src/org/sleuthkit/autopsy/scalpel/ScalpelCarverIngestModule.java @@ -100,7 +100,7 @@ class ScalpelCarverIngestModule extends IngestModuleAdapter implements FileInges // copy the default config file to the user's home directory if one // is not already there try { - PlatformUtil.extractResourceToUserConfigDir(this.getClass(), configFileName); + PlatformUtil.extractResourceToUserConfigDir(this.getClass(), configFileName, false); } catch (IOException ex) { String message = "Could not obtain the path to the Scalpel configuration file."; logger.log(Level.SEVERE, message, ex); diff --git a/git-daemon-export-okay b/git-daemon-export-okay new file mode 100644 index 0000000000..e69de29bb2