diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties new file mode 100755 index 0000000000..c903c40421 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties @@ -0,0 +1,2 @@ +IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings +IngestSettingsPanel.ignorePreviousNotableItemsCheckbox.text=Ignore previously seen notable items. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 09f3c63449..b3bf0505e6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,9 +55,11 @@ import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListen */ @Messages({"IngestModule.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)", "IngestModule.prevCaseComment.text=Previous Case: "}) -class IngestModule implements FileIngestModule { +final class IngestModule implements FileIngestModule { - private final static Logger LOGGER = Logger.getLogger(IngestModule.class.getName()); + static final boolean DEFAULT_IGNORE_PREVIOUS_NOTABLE_ITEMS = false; + + private final static Logger logger = Logger.getLogger(IngestModule.class.getName()); private final IngestServices services = IngestServices.getInstance(); private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); private static final IngestModuleReferenceCounter warningMsgRefCounter = new IngestModuleReferenceCounter(); @@ -66,6 +68,12 @@ class IngestModule implements FileIngestModule { private CorrelationDataSource eamDataSource; private Blackboard blackboard; private CorrelationAttribute.Type filesType; + + private final boolean ignorePreviousNotableItems; + + IngestModule(IngestSettings settings) { + ignorePreviousNotableItems = settings.isIgnorePreviousNotableItems(); + } @Override public ProcessResult process(AbstractFile af) { @@ -89,7 +97,7 @@ class IngestModule implements FileIngestModule { try { dbManager = EamDb.getInstance(); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); + logger.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); return ProcessResult.ERROR; } @@ -113,7 +121,7 @@ class IngestModule implements FileIngestModule { postCorrelatedBadFileToBlackboard(af, caseDisplayNames); } } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS return ProcessResult.ERROR; } } @@ -131,7 +139,7 @@ class IngestModule implements FileIngestModule { eamArtifact.addInstance(cefi); dbManager.prepareBulkArtifact(eamArtifact); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS return ProcessResult.ERROR; } @@ -148,19 +156,19 @@ class IngestModule implements FileIngestModule { try { dbManager = EamDb.getInstance(); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); + logger.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); return; } try { dbManager.bulkInsertArtifacts(); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error doing bulk insert of artifacts.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error doing bulk insert of artifacts.", ex); // NON-NLS } try { Long count = dbManager.getCountArtifactInstancesByCaseDataSource(eamCase.getCaseUUID(), eamDataSource.getDeviceID()); - LOGGER.log(Level.INFO, "{0} artifacts in db for case: {1} ds:{2}", new Object[]{count, eamCase.getDisplayName(), eamDataSource.getName()}); // NON-NLS + logger.log(Level.INFO, "{0} artifacts in db for case: {1} ds:{2}", new Object[]{count, eamCase.getDisplayName(), eamDataSource.getName()}); // NON-NLS } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error counting artifacts.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error counting artifacts.", ex); // NON-NLS } // TODO: once we implement shared cache, if refCounter is 1, then submit data in bulk. @@ -193,7 +201,7 @@ class IngestModule implements FileIngestModule { // Don't allow sqlite central repo databases to be used for multi user cases if ((Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE) && (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.SQLITE)) { - LOGGER.log(Level.SEVERE, "Cannot run correlation engine on a multi-user case with a SQLite central repository."); + logger.log(Level.SEVERE, "Cannot run correlation engine on a multi-user case with a SQLite central repository."); throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS } jobId = context.getJobId(); @@ -202,14 +210,14 @@ class IngestModule implements FileIngestModule { try { centralRepoDb = EamDb.getInstance(); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error connecting to central repository database.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error connecting to central repository database.", ex); // NON-NLS throw new IngestModuleException("Error connecting to central repository database.", ex); // NON-NLS } try { filesType = centralRepoDb.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS throw new IngestModuleException("Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS } Case autopsyCase = Case.getCurrentCase(); @@ -223,7 +231,7 @@ class IngestModule implements FileIngestModule { try { eamCase = centralRepoDb.newCase(autopsyCase); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error creating new case in ingest module start up.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error creating new case in ingest module start up.", ex); // NON-NLS throw new IngestModuleException("Error creating new case in ingest module start up.", ex); // NON-NLS } } @@ -231,7 +239,7 @@ class IngestModule implements FileIngestModule { try { eamDataSource = CorrelationDataSource.fromTSKDataSource(eamCase, context.getDataSource()); } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting data source info.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error getting data source info.", ex); // NON-NLS throw new IngestModuleException("Error getting data source info.", ex); // NON-NLS } // TODO: once we implement a shared cache, load/init it here w/ syncronized and define reference counter @@ -245,7 +253,7 @@ class IngestModule implements FileIngestModule { centralRepoDb.newDataSource(eamDataSource); } } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error adding data source to Central Repository.", ex); // NON-NLS + logger.log(Level.SEVERE, "Error adding data source to Central Repository.", ex); // NON-NLS throw new IngestModuleException("Error adding data source to Central Repository.", ex); // NON-NLS } @@ -268,7 +276,7 @@ class IngestModule implements FileIngestModule { // index the artifact for keyword search blackboard.indexArtifact(tifArtifact); } catch (Blackboard.BlackboardException ex) { - LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS + logger.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS } // send inbox message @@ -277,9 +285,9 @@ class IngestModule implements FileIngestModule { // fire event to notify UI of this new artifact services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT)); } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS + logger.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS } catch (IllegalStateException ex) { - LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS + logger.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java index ed3d4f0915..a0ec1f4329 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2015-2017 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +25,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.centralrepository.optionspanel.GlobalSettingsPanel; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; /** * Factory for Central Repository ingest modules @@ -34,8 +35,13 @@ import org.sleuthkit.autopsy.centralrepository.optionspanel.GlobalSettingsPanel; "IngestModuleFactory.ingestmodule.desc=Saves properties to the central repository for later correlation"}) public class IngestModuleFactory extends IngestModuleFactoryAdapter { - private static final String VERSION_NUMBER = "0.8.0"; + private static final String VERSION_NUMBER = "0.9.0"; + /** + * Get the name of the module. + * + * @return The module name. + */ static String getModuleName() { return Bundle.IngestModuleFactory_ingestmodule_name(); } @@ -76,5 +82,23 @@ public class IngestModuleFactory extends IngestModuleFactoryAdapter { globalOptionsPanel.load(); return globalOptionsPanel; } + + @Override + public IngestModuleIngestJobSettings getDefaultIngestJobSettings() { + return new IngestSettings(); + } + + @Override + public boolean hasIngestJobSettingsPanel() { + return true; + } + + @Override + public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { + if (!(settings instanceof IngestSettings)) { + throw new IllegalArgumentException("Expected settings argument to be an instance of IngestSettings"); + } + return new IngestSettingsPanel((IngestSettings) settings); + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java new file mode 100755 index 0000000000..e69e625b85 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java @@ -0,0 +1,71 @@ +/* + * Central Repository + * + * Copyright 2018 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.centralrepository.ingestmodule; + +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; + +/** + * Ingest job settings for the Correlation Engine module. + */ +final class IngestSettings implements IngestModuleIngestJobSettings { + + private static final long serialVersionUID = 1L; + + private boolean ignorePreviousNotableItems; + + /** + * Instantiate the ingest job settings with default values. + */ + IngestSettings() { + this.ignorePreviousNotableItems = IngestModule.DEFAULT_IGNORE_PREVIOUS_NOTABLE_ITEMS; + } + + /** + * Instantiate the ingest job settings. + * + * @param ignorePreviousNotableItems Ignore previously seen notable items. + */ + IngestSettings(boolean ignorePreviousNotableItems) { + this.ignorePreviousNotableItems = ignorePreviousNotableItems; + } + + @Override + public long getVersionNumber() { + return serialVersionUID; + } + + /** + * Are previously identified notable items ignored? + * + * @return True if ignored; otherwise false. + */ + boolean isIgnorePreviousNotableItems() { + return ignorePreviousNotableItems; + } + + /** + * Consider or ignore previously identified notable items. + * + * @param ignorePreviousNotableItems Are previously identified notable items + * ignored? + */ + void setIgnorePreviousNotableItems(boolean ignorePreviousNotableItems) { + this.ignorePreviousNotableItems = ignorePreviousNotableItems; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form new file mode 100755 index 0000000000..c60abee00d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form @@ -0,0 +1,70 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java new file mode 100755 index 0000000000..77e04d1528 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java @@ -0,0 +1,101 @@ +/* + * Central Repository + * + * Copyright 2018 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.centralrepository.ingestmodule; + +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; + +/** + * Ingest job settings panel for the Correlation Engine module. + */ +final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { + + /** + * Creates new form IngestModulePanel + */ + public IngestSettingsPanel(IngestSettings settings) { + initComponents(); + customizeComponents(settings); + } + + /** + * Update components with values from the ingest job settings. + * + * @param settings The ingest job settings. + */ + private void customizeComponents(IngestSettings settings) { + ignorePreviousNotableItemsCheckbox.setSelected(settings.isIgnorePreviousNotableItems()); + } + + @Override + public IngestModuleIngestJobSettings getSettings() { + return new IngestSettings(ignorePreviousNotableItemsCheckbox.isSelected()); + } + + /** + * 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() { + + ingestSettingsLabel = new javax.swing.JLabel(); + ignorePreviousNotableItemsCheckbox = new javax.swing.JCheckBox(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + + ingestSettingsLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(IngestSettingsPanel.class, "IngestSettingsPanel.ingestSettingsLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(ignorePreviousNotableItemsCheckbox, org.openide.util.NbBundle.getMessage(IngestSettingsPanel.class, "IngestSettingsPanel.ignorePreviousNotableItemsCheckbox.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().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() + .addGap(10, 10, 10) + .addComponent(ignorePreviousNotableItemsCheckbox)) + .addComponent(ingestSettingsLabel)) + .addContainerGap(83, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(ingestSettingsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(ignorePreviousNotableItemsCheckbox) + .addContainerGap(245, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox ignorePreviousNotableItemsCheckbox; + private javax.swing.JLabel ingestSettingsLabel; + // End of variables declaration//GEN-END:variables + +}