From 995701d9c8cf9bd15573f6c9185a9dc54157039a Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Fri, 27 Mar 2020 09:22:34 -0400 Subject: [PATCH 01/49] Added a properychange listener to HashLookupSettingsPanel --- .../hashdatabase/HashLookupSettingsPanel.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java index ebe59fe535..c0f5a05104 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java @@ -53,6 +53,7 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.CentralRepoHashS import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb; +import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.SetEvt; /** * Instances of this class provide a comprehensive UI for managing the hash sets @@ -94,6 +95,17 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan } } }); + + HashDbManager.getInstance().addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + String propName = evt.getPropertyName(); + if(propName.equals(SetEvt.DB_ADDED.toString()) || + propName.equals(SetEvt.DB_DELETED.toString())) { + hashSetTableModel.refreshModel(); + } + } + }); } @NbBundle.Messages({"HashLookupSettingsPanel.Title=Global Hash Lookup Settings"}) From 763acad24ce539d783a570a00851a09d6111f014 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 30 Mar 2020 09:28:11 -0400 Subject: [PATCH 02/49] multi user options panel label change --- .../autopsy/corecomponents/Bundle.properties | 6 +++--- .../autopsy/corecomponents/Bundle.properties-MERGED | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 15ee654347..4571bcc3df 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -77,9 +77,9 @@ DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails: {0} AboutWindowPanel.actVerboseLogging.text=Activate verbose logging OptionsCategory_Name_Multi_User_Settings=Multi-User OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings -MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings +MultiUserSettingsPanel.lbSolrSettings.text=Solr Server Settings MultiUserSettingsPanel.cbEnableMultiUser.text=Enable multi-user cases -MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings +MultiUserSettingsPanel.lbDatabaseSettings.text=Database Server Settings MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values MultiUserSettingsPanel.nonWindowsOs.msg=Multi-user cases are only available on Windows platforms MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number @@ -107,7 +107,7 @@ MultiUserSettingsPanel.tbSolrHostname.toolTipText=Hostname or IP Address MultiUserSettingsPanel.tbSolrPort.toolTipText=Port Number MultiUserSettingsPanel.lbTestMessageService.text= MultiUserSettingsPanel.bnTestMessageService.text=Test -MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Service Settings +MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Server Settings MultiUserSettingsPanel.tbMsgPort.toolTipText=Port Number MultiUserSettingsPanel.tbMsgPort.text= MultiUserSettingsPanel.tbMsgUsername.toolTipText=User Name (optional) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index f252420726..544cfa63c0 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
+LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
+LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ +DataResultViewerThumbnail.filePathLabel.text=\ \ \ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel @@ -129,9 +129,9 @@ DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails: {0} AboutWindowPanel.actVerboseLogging.text=Activate verbose logging OptionsCategory_Name_Multi_User_Settings=Multi-User OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings -MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings +MultiUserSettingsPanel.lbSolrSettings.text=Solr Server Settings MultiUserSettingsPanel.cbEnableMultiUser.text=Enable multi-user cases -MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings +MultiUserSettingsPanel.lbDatabaseSettings.text=Database Server Settings MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values MultiUserSettingsPanel.nonWindowsOs.msg=Multi-user cases are only available on Windows platforms MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number @@ -159,7 +159,7 @@ MultiUserSettingsPanel.tbSolrHostname.toolTipText=Hostname or IP Address MultiUserSettingsPanel.tbSolrPort.toolTipText=Port Number MultiUserSettingsPanel.lbTestMessageService.text= MultiUserSettingsPanel.bnTestMessageService.text=Test -MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Service Settings +MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Server Settings MultiUserSettingsPanel.tbMsgPort.toolTipText=Port Number MultiUserSettingsPanel.tbMsgPort.text= MultiUserSettingsPanel.tbMsgUsername.toolTipText=User Name (optional) From 6a95fcca57d4a2f183252cb68aa4ff33036f2d4a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 30 Mar 2020 10:21:54 -0400 Subject: [PATCH 03/49] mostly done with removing items that change settings --- .../datamodel/CentralRepoDbManager.java | 53 +--------------- .../optionspanel/GlobalSettingsPanel.java | 60 ++++++++++--------- 2 files changed, 34 insertions(+), 79 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 3fab7af47f..cbbfdc0b9c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -39,38 +39,23 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; private static final String CENTRAL_REPOSITORY_SETTINGS_KEY = "CentralRepository"; private static final String DB_SELECTED_PLATFORM_KEY = "db.selectedPlatform"; - private static final String DISABLED_DUE_TO_FAILURE_KEY = "disabledDueToFailure"; private static volatile CentralRepoDbChoice savedChoice = null; private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); private static final Object dbChoiceLock = new Object(); - private static final Object disabledDueToFailureLock = new Object(); - /** - * This saves the currently selected database choice and clears any disabledDueToFailure flag. - * @param choice The choice to save. - * @return The newly saved choice. - */ - public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { - return saveDbChoice(choice, true); - } - /** * This saves the currently selected database choice. * @param choice The choice to save. * @param clearDisabledDueToError Whether or not to clear the 'disabledDueToFailure' settings key. * @return The newly saved choice. */ - public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice, boolean clearDisabledDueToError) { + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { synchronized(dbChoiceLock) { - // clear disabling due to a failure - if (clearDisabledDueToError) - setDisabledDueToFailure(false); - // change the settings CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; CentralRepoDbChoice oldChoice = savedChoice; @@ -113,41 +98,7 @@ public class CentralRepoDbManager { } } - /** - * This method disables the central repository and indicates through a flag that this was due to a failure during database setup. - * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - */ - public static void disableDueToFailure() { - CentralRepoDbUtil.setUseCentralRepo(false); - setDisabledDueToFailure(true); - } - /** - * This method sets whether or not the repository has been disabled due to a database setup issue; - * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - * - * @param disabledDueToFailure Whether or not the repository has been disabled due to a database setup issue. - */ - private static void setDisabledDueToFailure(boolean disabledDueToFailure) { - synchronized(disabledDueToFailureLock) { - boolean oldValue = isDisabledDueToFailure(); - ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); - propertyChangeSupport.firePropertyChange("disabledDueToFailure", oldValue, disabledDueToFailure); - } - } - - /** - * This method retrieves setting whether or not the repository has been disabled due to a database setup issue; - * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - * - * @return Whether or not the repository has been disabled due to a database setup issue. - */ - public static boolean isDisabledDueToFailure() { - synchronized(disabledDueToFailureLock) { - return Boolean.toString(true).equals(ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY)); - } - } - /** * This method adds a property change listener. * NOTE: currently only listening for changes in currently saved db choice and disabling due to failure. @@ -288,7 +239,7 @@ public class CentralRepoDbManager { } catch (CentralRepoException ex2) { logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } - saveDbChoice(CentralRepoDbChoice.DISABLED, false); + saveDbChoice(CentralRepoDbChoice.DISABLED); if (innerException == null) { throw new CentralRepoException(message, desc); } else { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index bdf1839526..23e25db520 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.centralrepository.optionspanel; -import java.awt.Cursor; import java.awt.EventQueue; import org.sleuthkit.autopsy.coreutils.Logger; import java.beans.PropertyChangeEvent; @@ -44,6 +43,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSett import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; import java.util.logging.Level; +import org.sleuthkit.autopsy.centralrepository.optionspanel.Bundle; + + /** * Main settings panel for the Central Repository @@ -121,24 +123,23 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository(); boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; - boolean crDisabledDueToFailure = CentralRepoDbManager.isDisabledDueToFailure(); if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, "" + "
" - + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "

" - + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "

" + + "

" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description() + "

" + + "

" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description2() + "

" + "
" + "", - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_title(), JOptionPane.YES_NO_OPTION)) { // setup database for CR CentralRepoDbUtil.setUseCentralRepo(true); CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - handleDbChange(parent); + checkStatusAndCreateDb(parent); } }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected @@ -148,12 +149,22 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i }); } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && // central repo either enabled or was disabled due to error - else if (muPreviouslySelected && muCurrentlySelected && crMultiUser && (crEnabled || crDisabledDueToFailure)) { - // test databse for CR change - CentralRepoDbUtil.setUseCentralRepo(true); - handleDbChange(parent); + else if (muPreviouslySelected && muCurrentlySelected && crEnabled && crMultiUser) { + checkStatusAndCreateDb(parent); } } + + + /** + * Checks the status of current connectivity for CR and reports any issues. Will also prompt user to create + * database if cr database is absent. + * @param parent the parent component to which the dialogs will be associated. + */ + private static void checkStatusAndCreateDb(Component parent) { + SwingUtilities.invokeLater(() -> { + EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); + }); + } /** * This method is called when a user must select a new database other than @@ -165,28 +176,27 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.", - "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database." + "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database.", + "GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite", + "GlobalSettingsPanel.askForCentralRepoDbChoice.customPostgrestChoice.text=Configure PostgreSQL", + "GlobalSettingsPanel.askForCentralRepoDbChoice.disableChoice.text=Disable Central Repository" }) private static void askForCentralRepoDbChoice(Component parent) { - // disable central repository until user makes choice - CentralRepoDbUtil.setUseCentralRepo(false); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED, false); - Object[] options = { - "Use SQLite", - "Configure PostgreSQL", - "Disable Central Repository" + Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_sqliteChoice_text(), + Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_customPostgrestChoice_text(), + Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_disableChoice_text() }; int result = JOptionPane.showOptionDialog( parent, "" + "
" - + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" - + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "

" + + "

" + Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_description() + "

" + + "

" + Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_description2() + "

" + "
" + "", - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), + Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_title(), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, @@ -201,13 +211,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } } - private static void handleDbChange(Component parent) { - SwingUtilities.invokeLater(() -> { - if (!EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager())) { - CentralRepoDbManager.disableDueToFailure(); - } - }); - } + /** * This method is called from within the constructor to initialize the form. From 883c494e3d10bccc99ed5d3b4423916aaae1cf38 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 30 Mar 2020 13:20:10 -0400 Subject: [PATCH 04/49] working to create test button --- .../optionspanel/Bundle.properties | 3 ++ .../optionspanel/Bundle_ja.properties | 2 + .../optionspanel/GlobalSettingsPanel.form | 43 +++++++++++++++--- .../optionspanel/GlobalSettingsPanel.java | 44 ++++++++++++++++--- 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties index 0b30e2584f..a9f4326b26 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties @@ -84,3 +84,6 @@ ManageCasesDialog.closeButton.text=Close ManageCasesDialog.notesLabel.text=Notes: ManageCasesDialog.dataSourcesLabel.text=Data Sources: ManageCasesDialog.caseInfoLabel.text=Case Info: +GlobalSettingsPanel.bnTestConfigure.text=Test +GlobalSettingsPanel.testStatusLabel.toolTipText= +GlobalSettingsPanel.testStatusLabel.text= diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties index 96e0634149..e1c3de35ad 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties @@ -143,3 +143,5 @@ ManageCasesDialog.closeButton.text=\u9589\u3058\u308b ManageCasesDialog.notesLabel.text=\u5099\u8003: ManageCasesDialog.dataSourcesLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9: ManageCasesDialog.caseInfoLabel.text=\u30b1\u30fc\u30b9\u60c5\u5831: +GlobalSettingsPanel.bnTestConfigure.text=\u69cb\u6210 +GlobalSettingsPanel.testStatusLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5b9f\u884c\u4e2d\u306f\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u8a2d\u5b9a\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093! diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 99594871b0..99e350375f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -138,10 +138,6 @@ - - - - @@ -155,6 +151,14 @@ + + + + + + + + @@ -178,7 +182,11 @@ - + + + + + @@ -222,6 +230,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 23e25db520..46e279c17e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -234,6 +234,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i lbDbPlatformValue = new javax.swing.JLabel(); lbDbNameValue = new javax.swing.JLabel(); lbDbLocationValue = new javax.swing.JLabel(); + bnTestConfigure = new javax.swing.JButton(); + testStatusLabel = new javax.swing.JLabel(); pnCorrelationProperties = new javax.swing.JPanel(); bnManageTypes = new javax.swing.JButton(); correlationPropertiesScrollPane = new javax.swing.JScrollPane(); @@ -282,6 +284,17 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } }); + org.openide.awt.Mnemonics.setLocalizedText(bnTestConfigure, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnTestConfigure.text")); // NOI18N + bnTestConfigure.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnTestConfigureActionPerformed(evt); + } + }); + + testStatusLabel.setFont(testStatusLabel.getFont().deriveFont(testStatusLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(testStatusLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.text")); // NOI18N + testStatusLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.toolTipText")); // NOI18N + javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration); pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout); pnDatabaseConfigurationLayout.setHorizontalGroup( @@ -289,9 +302,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addContainerGap() .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() - .addComponent(bnDbConfigure) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -301,7 +311,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 936, Short.MAX_VALUE) .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))) + .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() + .addComponent(bnDbConfigure) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(bnTestConfigure) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 836, Short.MAX_VALUE) + .addContainerGap()))) ); pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -319,7 +336,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnDbConfigure) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnDbConfigure) + .addComponent(bnTestConfigure) + .addComponent(testStatusLabel)) .addGap(8, 8, 8)) ); @@ -364,7 +384,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i pnCorrelationPropertiesLayout.setVerticalGroup( pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnCorrelationPropertiesLayout.createSequentialGroup() - .addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 32, Short.MAX_VALUE) + .addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(bnManageTypes) .addGap(8, 8, 8)) @@ -480,7 +500,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1012, Short.MAX_VALUE) + .addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1016, Short.MAX_VALUE) .addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() @@ -571,6 +591,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed + private void bnTestConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConfigureActionPerformed + testCurrentConfiguration(); + }//GEN-LAST:event_bnTestConfigureActionPerformed + @Override @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."}) public void load() { @@ -699,6 +723,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } + + /** * Enable the Configure button @@ -710,8 +736,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void enableDatabaseConfigureButton(Boolean enable) { boolean ingestRunning = IngestManager.getInstance().isIngestRunning(); ingestRunningWarningLabel.setVisible(ingestRunning); + pnDatabaseConfiguration.setEnabled(enable && !ingestRunning); bnDbConfigure.setEnabled(enable && !ingestRunning); + bnTestConfigure.setEnabled(enable && !ingestRunning); lbDbLocationLabel.setEnabled(enable && !ingestRunning); lbDbLocationValue.setEnabled(enable && !ingestRunning); lbDbNameLabel.setEnabled(enable && !ingestRunning); @@ -746,6 +774,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnDbConfigure; private javax.swing.JButton bnManageTypes; + private javax.swing.JButton bnTestConfigure; private javax.swing.JPanel casesPanel; private javax.swing.JScrollPane casesScrollPane; private javax.swing.JTextArea casesTextArea; @@ -770,5 +799,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private javax.swing.JPanel pnDatabaseConfiguration; private javax.swing.JButton showCasesButton; private javax.swing.JTextField tbOops; + private javax.swing.JLabel testStatusLabel; // End of variables declaration//GEN-END:variables } From 279a5a461356093284eef9730b2e6bbd3b347fe9 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 31 Mar 2020 08:17:44 -0400 Subject: [PATCH 05/49] update in global settings panel for updates --- .../datamodel/CentralRepoDbManager.java | 70 ++++++++++------- .../CentralRepoDbUpgrader13To14.java | 2 +- .../datamodel/CentralRepository.java | 4 +- .../datamodel/CentralRepositoryService.java | 2 +- .../PostgresCentralRepoSettings.java | 2 +- .../datamodel/RdbmsCentralRepo.java | 2 +- .../eventlisteners/Installer.java | 3 +- .../ingestmodule/CentralRepoIngestModule.java | 2 +- .../optionspanel/EamDbSettingsDialog.java | 55 +++++++------ .../optionspanel/GlobalSettingsPanel.java | 78 ++++++++++++++----- 10 files changed, 141 insertions(+), 79 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index cbbfdc0b9c..374fd35048 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -39,12 +39,39 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; private static final String CENTRAL_REPOSITORY_SETTINGS_KEY = "CentralRepository"; private static final String DB_SELECTED_PLATFORM_KEY = "db.selectedPlatform"; + + private static CentralRepoDbManager instance = null; + + public static CentralRepoDbManager getInstance() { + if (instance == null) + instance = new CentralRepoDbManager(); + + return instance; + } - private static volatile CentralRepoDbChoice savedChoice = null; - private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); + // The currently saved db choice. + private volatile CentralRepoDbChoice savedChoice = null; + private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); + private final Object dbChoiceLock = new Object(); + + // The currently selected (but not necessarily saved) central repo db choice. + private CentralRepoDbChoice selectedDbChoice; + + private boolean configurationChanged = false; + private DatabaseTestResult testingStatus; + + private final PostgresCentralRepoSettings dbSettingsPostgres; + private final PostgresCentralRepoSettings dbSettingsMultiUser; + private final SqliteCentralRepoSettings dbSettingsSqlite; + + private CentralRepoDbManager() { + selectedDbChoice = getSavedDbChoice(); + dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER); + dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); + dbSettingsSqlite = new SqliteCentralRepoSettings(); + } - private static final Object dbChoiceLock = new Object(); @@ -54,7 +81,7 @@ public class CentralRepoDbManager { * @param clearDisabledDueToError Whether or not to clear the 'disabledDueToFailure' settings key. * @return The newly saved choice. */ - public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + public CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { synchronized(dbChoiceLock) { // change the settings CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; @@ -71,7 +98,7 @@ public class CentralRepoDbManager { * This method indicates whether or not 'PostgreSQL using multi-user settings' is a valid option. * @return True if 'PostgreSQL using multi-user settings' is valid. */ - public static boolean isPostgresMultiuserAllowed() { + public boolean isPostgresMultiuserAllowed() { // if multi user mode is not enabled, then this cannot be used if (!UserPreferences.getIsMultiUserModeEnabled()) return false; @@ -87,7 +114,7 @@ public class CentralRepoDbManager { /** * This method loads the selectedPlatform boolean from the config file if it is set. */ - public static CentralRepoDbChoice getSavedDbChoice() { + public CentralRepoDbChoice getSavedDbChoice() { synchronized(dbChoiceLock) { if (savedChoice == null) { String selectedPlatformString = ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DB_SELECTED_PLATFORM_KEY); // NON-NLS @@ -105,7 +132,7 @@ public class CentralRepoDbManager { * * @param listener The listener for the event. */ - public static void addPropertyChangeListener(PropertyChangeListener listener) { + public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } @@ -113,13 +140,13 @@ public class CentralRepoDbManager { * This method removes a propert change listener. * @param listener The listener to remove. */ - public static void removePropertyChangeListener(PropertyChangeListener listener) { + public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } - private static CentralRepoDbChoice fromKey(String keyName) { + private CentralRepoDbChoice fromKey(String keyName) { for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.values()) { if (dbChoice.getSettingKey().equalsIgnoreCase(keyName)) { return dbChoice; @@ -137,7 +164,7 @@ public class CentralRepoDbManager { * @return The CentralRepository object that will be used for connection. * @throws CentralRepoException */ - private static CentralRepository obtainCentralRepository() throws CentralRepoException { + private CentralRepository obtainCentralRepository() throws CentralRepoException { //get connection try { return CentralRepository.getInstance(); @@ -158,7 +185,7 @@ public class CentralRepoDbManager { * @return The lock if acquired. * @throws CentralRepoException */ - private static CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { + private CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { try { // This may return null if locking isn't supported, which is fine. It will // throw an exception if locking is supported but we can't get the lock @@ -182,7 +209,7 @@ public class CentralRepoDbManager { * @param lock The acquired lock. * @throws CentralRepoException */ - private static void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { + private void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { try { db.upgradeSchema(); } catch (CentralRepoException ex) { @@ -213,7 +240,7 @@ public class CentralRepoDbManager { * settings will be cleared. */ @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) - public static void upgradeDatabase() throws CentralRepoException { + public void upgradeDatabase() throws CentralRepoException { if (!CentralRepository.isEnabled()) { return; } @@ -230,7 +257,7 @@ public class CentralRepoDbManager { } } - private static void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { + private void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { // Disable the central repo and clear the current settings. try { if (null != CentralRepository.getInstance()) { @@ -249,21 +276,6 @@ public class CentralRepoDbManager { - private DatabaseTestResult testingStatus; - private CentralRepoDbChoice selectedDbChoice; - - private final PostgresCentralRepoSettings dbSettingsPostgres; - private final PostgresCentralRepoSettings dbSettingsMultiUser; - private final SqliteCentralRepoSettings dbSettingsSqlite; - - private boolean configurationChanged = false; - - public CentralRepoDbManager() { - selectedDbChoice = getSavedDbChoice(); - dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER); - dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); - dbSettingsSqlite = new SqliteCentralRepoSettings(); - } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index 0acfd34ea5..944703f532 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -39,7 +39,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { try (Statement statement = connection.createStatement();) { - CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); + CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); // Create account_types and accounts tables which are referred by X_instances tables statement.execute(RdbmsCentralRepoFactory.getCreateAccountTypesTableStatement(selectedPlatform)); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 6a4a138cfb..5106f133b4 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -42,7 +42,7 @@ public interface CentralRepository { CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.DISABLED; if (CentralRepoDbUtil.allowUseOfCentralRepository()) { - selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); + selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); } switch (selectedPlatform) { case POSTGRESQL: @@ -93,7 +93,7 @@ public interface CentralRepository { */ static boolean isEnabled() { return CentralRepoDbUtil.allowUseOfCentralRepository() - && CentralRepoDbManager.getSavedDbChoice() != CentralRepoDbChoice.DISABLED; + && CentralRepoDbManager.getInstance().getSavedDbChoice() != CentralRepoDbChoice.DISABLED; } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java index 8b442efc24..4a02c50569 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java @@ -69,7 +69,7 @@ public class CentralRepositoryService implements AutopsyService { */ private void updateSchema() throws AutopsyServiceException { try { - CentralRepoDbManager.upgradeDatabase(); + CentralRepoDbManager.getInstance().upgradeDatabase(); } catch (CentralRepoException ex) { throw new AutopsyServiceException("Failed to update the Central Repository schema", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 165d4ca6e0..68765cf259 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -46,7 +46,7 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv private PostgresConnectionSettings connSettings; private static PostgresSettingsLoader getLoaderFromSaved() throws CentralRepoException { - CentralRepoDbChoice choice = CentralRepoDbManager.getSavedDbChoice(); + CentralRepoDbChoice choice = CentralRepoDbManager.getInstance().getSavedDbChoice(); if (choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER; else if (choice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 256e5407c9..c0642bc59f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -3528,7 +3528,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { conn = connect(false); conn.setAutoCommit(false); statement = conn.createStatement(); - selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); + selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); int minorVersion = 0; String minorVersionStr = null; resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "'"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index da58e8936b..ff64ae56f7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -181,8 +181,7 @@ public class Installer extends ModuleInstall { * repository. */ private void setupDefaultSqliteCentralRepo() throws CentralRepoException { - CentralRepoDbManager manager = new CentralRepoDbManager(); - manager.setupDefaultSqliteDb(); + CentralRepoDbManager.getInstance().setupDefaultSqliteDb(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index 1f7472d330..db44477eb2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -275,7 +275,7 @@ final class CentralRepoIngestModule implements FileIngestModule { // Don't allow sqlite central repo databases to be used for multi user cases if ((autopsyCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) - && (CentralRepoDbManager.getSavedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE)) { + && (CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE)) { 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 } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 4c70d6aa5c..0cc58d94bd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -86,8 +86,7 @@ public class EamDbSettingsDialog extends JDialog { private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; - private final CentralRepoDbManager manager = new CentralRepoDbManager(); - private final boolean isMultiUserSelectable = CentralRepoDbManager.isPostgresMultiuserAllowed(); + private final CentralRepoDbManager manager = CentralRepoDbManager.getInstance(); private final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); public EamDbSettingsDialog() { @@ -95,7 +94,7 @@ public class EamDbSettingsDialog extends JDialog { } private boolean isDbChoiceSelectable(CentralRepoDbChoice item) { - return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || isMultiUserSelectable); + return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || manager.isPostgresMultiuserAllowed()); } @@ -181,31 +180,43 @@ public class EamDbSettingsDialog extends JDialog { Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), JOptionPane.WARNING_MESSAGE); } else if (manager.getStatus() == DatabaseTestResult.DB_DOES_NOT_EXIST) { - //database doesn't exist. do you want to create? - if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), - JOptionPane.YES_NO_OPTION)) { - onUserPromptCreateDb(manager, dialog); - } + promptCreateDatabase(manager, dialog); } return (manager.getStatus() == DatabaseTestResult.TESTED_OK); } - - /** - * When a new database needs to be created on user selecting cr, this code will be ran when user selects create cr. - * @param manager The manager handling the database creation. - * @param dialog The dialog that prompted database creation. + + + /** + * This method prompts the user whether or not they would like to create a database in the instance that + * it doesn't exist. + * @param manager The manager to use when setting up the database. + * @param dialog If non-null value, validates settings and updates 'okay' + * button enabled state. + * + * @return Whether or not the ultimate status after prompts is okay. */ - private static void onUserPromptCreateDb(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { - try { - manager.createDb(); - } catch (CentralRepoException e) { - onPromptStatusError(manager); + public static boolean promptCreateDatabase(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { + //database doesn't exist. do you want to create? + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), + JOptionPane.YES_NO_OPTION)) { + try { + manager.createDb(); + + } catch (CentralRepoException e) { + onPromptStatusError(manager); + return false; + } + + if (dialog != null) { + dialog.valid(); + } + return true; } - if (dialog != null) - dialog.valid(); + + return manager.testStatus() == DatabaseTestResult.TESTED_OK; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 46e279c17e..6cca8f73b7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -43,6 +43,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSett import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; import java.util.logging.Level; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; +import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.optionspanel.Bundle; @@ -56,16 +59,22 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName()); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); - private final IngestJobEventPropertyChangeListener ingestJobEventListener; + private final IngestJobEventPropertyChangeListener ingestJobEventListener; + private final CentralRepoDbManager manager; + + private final ImageIcon goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); + private final ImageIcon badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); + /** * Creates new form EamOptionsPanel */ public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - + manager = CentralRepoDbManager.getInstance(); + // listen for change events in currently saved choice - CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen())); + manager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen())); initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -121,8 +130,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { + CentralRepoDbManager manager = CentralRepoDbManager.getInstance(); boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository(); - boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; + boolean crMultiUser = manager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { @@ -138,8 +148,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // setup database for CR CentralRepoDbUtil.setUseCentralRepo(true); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - checkStatusAndCreateDb(parent); + manager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); + checkStatusAndCreateDb(manager, parent); } }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected @@ -150,7 +160,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && // central repo either enabled or was disabled due to error else if (muPreviouslySelected && muCurrentlySelected && crEnabled && crMultiUser) { - checkStatusAndCreateDb(parent); + checkStatusAndCreateDb(manager, parent); } } @@ -160,9 +170,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * database if cr database is absent. * @param parent the parent component to which the dialogs will be associated. */ - private static void checkStatusAndCreateDb(Component parent) { + private static void checkStatusAndCreateDb(CentralRepoDbManager manager, Component parent) { SwingUtilities.invokeLater(() -> { - EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); + EamDbSettingsDialog.testStatusAndCreate(parent, manager); }); } @@ -210,8 +220,47 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i invokeCrChoice(parent, CentralRepoDbChoice.POSTGRESQL_CUSTOM); } } + + @NbBundle.Messages({ + "GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.", + }) + private boolean testCurrentConfiguration() { + DatabaseTestResult testResult = manager.testStatus(); + // if database doesn't exist, prompt user to create database + if (testResult == DatabaseTestResult.DB_DOES_NOT_EXIST) { + boolean success = EamDbSettingsDialog.promptCreateDatabase(manager, null); + if (success) + testResult = DatabaseTestResult.TESTED_OK; + } + + // display to the user the status + switch (testResult) { + case TESTED_OK: return showStatusOkay(); + case DB_DOES_NOT_EXIST: return showStatusFail(Bundle.GlobalSettingsPanel_testCurrentConfiguration_dbDoesNotExist_message()); + case SCHEMA_INVALID: return showStatusFail(Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message()); + case CONNECTION_FAILED: + default: + return showStatusFail(Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message()); + } + } + private boolean showStatusOkay() { + return setStatus(goodIcon, null); + } + + private boolean showStatusFail(String message) { + return setStatus(badIcon, message); + } + private void clearStatus() { + setStatus(null, null); + } + + private boolean setStatus(ImageIcon icon, String text) { + testStatusLabel.setIcon(icon); + testStatusLabel.setText(text); + return true; + } /** * This method is called from within the constructor to initialize the form. @@ -577,15 +626,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed //if saved setting is disabled checkbox should be disabled already store(); - - // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled - if (cbUseCentralRepo.isSelected() - && !CentralRepoDbManager.isPostgresMultiuserAllowed() - && CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { - - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - } - load(); this.ingestStateUpdated(Case.isCaseOpen()); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); @@ -600,7 +640,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i public void load() { tbOops.setText(""); enableButtonSubComponents(false); - CentralRepoDbChoice selectedChoice = CentralRepoDbManager.getSavedDbChoice(); + CentralRepoDbChoice selectedChoice = manager.getSavedDbChoice(); cbUseCentralRepo.setSelected(CentralRepoDbUtil.allowUseOfCentralRepository()); // NON-NLS lbDbPlatformValue.setText(selectedChoice.getTitle()); From 3fdd5cd5c185e15396583c0db587cd337d085108 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 11:07:05 -0400 Subject: [PATCH 06/49] updates to central repo db manager --- .../datamodel/CentralRepoDbManager.java | 75 ++++++++++++------- .../optionspanel/EamDbSettingsDialog.java | 12 +-- .../optionspanel/GlobalSettingsPanel.form | 14 ++-- .../optionspanel/GlobalSettingsPanel.java | 44 ++++++----- 4 files changed, 81 insertions(+), 64 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 374fd35048..d551f88d46 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -50,15 +50,14 @@ public class CentralRepoDbManager { } - // The currently saved db choice. - private volatile CentralRepoDbChoice savedChoice = null; private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); private final Object dbChoiceLock = new Object(); + // The currently saved db choice. + private volatile CentralRepoDbChoice savedChoice = null; + // The currently selected (but not necessarily saved) central repo db choice. private CentralRepoDbChoice selectedDbChoice; - - private boolean configurationChanged = false; private DatabaseTestResult testingStatus; private final PostgresCentralRepoSettings dbSettingsPostgres; @@ -328,30 +327,28 @@ public class CentralRepoDbManager { saveNewCentralRepo(); } - /** - * This method returns if changes to the central repository configuration were - * successfully applied. - * - * @return Returns true if the database configuration was successfully changed false - * if it was not. - */ - public boolean wasConfigurationChanged() { - return configurationChanged; + private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { + return getSettings(getSelectedDbChoice()); } - private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + private CentralRepoDbConnectivityManager getSavedSettings() throws CentralRepoException { + return getSettings(getSavedDbChoice()); + } + + private CentralRepoDbConnectivityManager getSettings(CentralRepoDbChoice dbChoice) throws CentralRepoException { + if (dbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) return dbSettingsMultiUser; - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + if (dbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return dbSettingsPostgres; - if (selectedDbChoice == CentralRepoDbChoice.SQLITE) + if (dbChoice == CentralRepoDbChoice.SQLITE) return dbSettingsSqlite; - if (selectedDbChoice == CentralRepoDbChoice.DISABLED) + if (dbChoice == CentralRepoDbChoice.DISABLED) return null; - throw new CentralRepoException("Unknown database type: " + selectedDbChoice); + throw new CentralRepoException("Unknown database type: " + dbChoice); } - + + private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsMultiUser); @@ -408,7 +405,7 @@ public class CentralRepoDbManager { } /** - * This method saves a new central repository based on current settings. + * This method saves a new central repository based on current selected settings. */ @NbBundle.Messages({"CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database."}) public void saveNewCentralRepo() throws CentralRepoException { @@ -447,7 +444,6 @@ public class CentralRepoDbManager { try { logger.info("Saving central repo settings for db: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); - configurationChanged = true; } catch (CentralRepoException ex) { logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS return; @@ -479,6 +475,14 @@ public class CentralRepoDbManager { public void clearStatus() { testingStatus = DatabaseTestResult.UNTESTED; } + + /** + * Resets selected db choice to currently saved choice. + */ + public void resetSelectedDbChoice() { + setSelctedDbChoice(getSavedDbChoice()); + } + /** * This method sets the currently selected database choice and sets the testing status to untested. @@ -518,19 +522,38 @@ public class CentralRepoDbManager { } /** - * This method tests the current database settings to see if a valid connection can be made. + * This method tests the current selected (not necessarily saved) database settings to see if a valid connection can be made. * @return The result of testing the connection. */ public DatabaseTestResult testStatus() { + CentralRepoDbConnectivityManager manager = null; try { - CentralRepoDbConnectivityManager manager = getSelectedSettings(); - if (manager != null) - testingStatus = manager.testStatus(); + manager = getSelectedSettings(); } catch (CentralRepoException e) { logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); } + return testStatus(manager); + } + + + public DatabaseTestResult testSavedStatus() { + CentralRepoDbConnectivityManager manager = null; + try { + manager = getSavedSettings(); + } + catch (CentralRepoException e) { + logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); + } + + return testStatus(manager); + } + + private DatabaseTestResult testStatus(CentralRepoDbConnectivityManager manager) { + if (manager != null) + testingStatus = manager.testStatus(); + return testingStatus; } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 0cc58d94bd..d6d620bb6d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -586,19 +586,9 @@ public class EamDbSettingsDialog extends JDialog { parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return true; } - - /** - * This method returns if changes to the central repository configuration were - * successfully applied. - * - * @return True if the database configuration was successfully changed; false - * if it was not. - */ - public boolean wasConfigurationChanged() { - return manager.wasConfigurationChanged(); - } private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed + manager.resetSelectedDbChoice(); dispose(); }//GEN-LAST:event_bnCancelActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 99e350375f..1dfe191420 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -67,7 +67,7 @@ - + @@ -146,18 +146,18 @@ - + - + - - - + + + @@ -185,7 +185,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 6cca8f73b7..1fbe5e0b31 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -74,7 +74,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i manager = CentralRepoDbManager.getInstance(); // listen for change events in currently saved choice - manager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen())); + manager.addPropertyChangeListener((PropertyChangeEvent evt) -> { + //ingestStateUpdated(Case.isCaseOpen()); + + load(); // reload db settings content and update buttons + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + clearStatus(); + }); + initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -104,11 +111,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * * @return True if there was a change. */ - private static boolean invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { + private static void invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { EamDbSettingsDialog dialog = (initialSelection != null) - ? new EamDbSettingsDialog(initialSelection) - : new EamDbSettingsDialog(); - return dialog.wasConfigurationChanged(); + ? new EamDbSettingsDialog(initialSelection) + : new EamDbSettingsDialog(); } /** @@ -257,9 +263,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } private boolean setStatus(ImageIcon icon, String text) { - testStatusLabel.setIcon(icon); - testStatusLabel.setText(text); - return true; + synchronized (testStatusLabel) { + testStatusLabel.setIcon(icon); + testStatusLabel.setText(text); + return true; + } } /** @@ -358,16 +366,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(lbDbLocationLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 936, Short.MAX_VALUE) + .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addComponent(bnDbConfigure) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(18, 18, 18) .addComponent(bnTestConfigure) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 836, Short.MAX_VALUE) - .addContainerGap()))) + .addGap(18, 18, 18) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 805, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(19, Short.MAX_VALUE)))) ); pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -388,7 +396,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnDbConfigure) .addComponent(bnTestConfigure) - .addComponent(testStatusLabel)) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(8, 8, 8)) ); @@ -555,7 +563,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(cbUseCentralRepo, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 844, Short.MAX_VALUE)) + .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 974, javax.swing.GroupLayout.PREFERRED_SIZE))) @@ -606,11 +614,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); - boolean changed = invokeCrChoice(this, null); - if (changed) { - load(); // reload db settings content and update buttons - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } + invokeCrChoice(this, null); }//GEN-LAST:event_bnDbConfigureActionPerformed private void manageOrganizationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageOrganizationButtonActionPerformed From 56f3546baedce6e82bd8eea988a435759c83d1ab Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 11:37:52 -0400 Subject: [PATCH 07/49] updates to spacing --- .../datamodel/CentralRepoDbManager.java | 192 ++++++++++-------- .../CentralRepoDbUpgrader13To14.java | 2 +- .../datamodel/CentralRepository.java | 4 +- .../datamodel/CentralRepositoryService.java | 2 +- .../PostgresCentralRepoSettings.java | 2 +- .../datamodel/RdbmsCentralRepo.java | 2 +- .../eventlisteners/Installer.java | 3 +- .../ingestmodule/CentralRepoIngestModule.java | 2 +- .../optionspanel/EamDbSettingsDialog.java | 15 +- .../optionspanel/GlobalSettingsPanel.form | 6 + .../optionspanel/GlobalSettingsPanel.java | 33 +-- 11 files changed, 148 insertions(+), 115 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index d551f88d46..3fab7af47f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -39,40 +39,25 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; private static final String CENTRAL_REPOSITORY_SETTINGS_KEY = "CentralRepository"; private static final String DB_SELECTED_PLATFORM_KEY = "db.selectedPlatform"; + private static final String DISABLED_DUE_TO_FAILURE_KEY = "disabledDueToFailure"; + + private static volatile CentralRepoDbChoice savedChoice = null; - private static CentralRepoDbManager instance = null; + private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); - public static CentralRepoDbManager getInstance() { - if (instance == null) - instance = new CentralRepoDbManager(); - - return instance; + private static final Object dbChoiceLock = new Object(); + private static final Object disabledDueToFailureLock = new Object(); + + + + /** + * This saves the currently selected database choice and clears any disabledDueToFailure flag. + * @param choice The choice to save. + * @return The newly saved choice. + */ + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + return saveDbChoice(choice, true); } - - - private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); - private final Object dbChoiceLock = new Object(); - - // The currently saved db choice. - private volatile CentralRepoDbChoice savedChoice = null; - - // The currently selected (but not necessarily saved) central repo db choice. - private CentralRepoDbChoice selectedDbChoice; - private DatabaseTestResult testingStatus; - - private final PostgresCentralRepoSettings dbSettingsPostgres; - private final PostgresCentralRepoSettings dbSettingsMultiUser; - private final SqliteCentralRepoSettings dbSettingsSqlite; - - private CentralRepoDbManager() { - selectedDbChoice = getSavedDbChoice(); - dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER); - dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); - dbSettingsSqlite = new SqliteCentralRepoSettings(); - } - - - /** * This saves the currently selected database choice. @@ -80,8 +65,12 @@ public class CentralRepoDbManager { * @param clearDisabledDueToError Whether or not to clear the 'disabledDueToFailure' settings key. * @return The newly saved choice. */ - public CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice, boolean clearDisabledDueToError) { synchronized(dbChoiceLock) { + // clear disabling due to a failure + if (clearDisabledDueToError) + setDisabledDueToFailure(false); + // change the settings CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; CentralRepoDbChoice oldChoice = savedChoice; @@ -97,7 +86,7 @@ public class CentralRepoDbManager { * This method indicates whether or not 'PostgreSQL using multi-user settings' is a valid option. * @return True if 'PostgreSQL using multi-user settings' is valid. */ - public boolean isPostgresMultiuserAllowed() { + public static boolean isPostgresMultiuserAllowed() { // if multi user mode is not enabled, then this cannot be used if (!UserPreferences.getIsMultiUserModeEnabled()) return false; @@ -113,7 +102,7 @@ public class CentralRepoDbManager { /** * This method loads the selectedPlatform boolean from the config file if it is set. */ - public CentralRepoDbChoice getSavedDbChoice() { + public static CentralRepoDbChoice getSavedDbChoice() { synchronized(dbChoiceLock) { if (savedChoice == null) { String selectedPlatformString = ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DB_SELECTED_PLATFORM_KEY); // NON-NLS @@ -124,14 +113,48 @@ public class CentralRepoDbManager { } } + /** + * This method disables the central repository and indicates through a flag that this was due to a failure during database setup. + * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. + */ + public static void disableDueToFailure() { + CentralRepoDbUtil.setUseCentralRepo(false); + setDisabledDueToFailure(true); + } + /** + * This method sets whether or not the repository has been disabled due to a database setup issue; + * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. + * + * @param disabledDueToFailure Whether or not the repository has been disabled due to a database setup issue. + */ + private static void setDisabledDueToFailure(boolean disabledDueToFailure) { + synchronized(disabledDueToFailureLock) { + boolean oldValue = isDisabledDueToFailure(); + ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); + propertyChangeSupport.firePropertyChange("disabledDueToFailure", oldValue, disabledDueToFailure); + } + } + + /** + * This method retrieves setting whether or not the repository has been disabled due to a database setup issue; + * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. + * + * @return Whether or not the repository has been disabled due to a database setup issue. + */ + public static boolean isDisabledDueToFailure() { + synchronized(disabledDueToFailureLock) { + return Boolean.toString(true).equals(ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY)); + } + } + /** * This method adds a property change listener. * NOTE: currently only listening for changes in currently saved db choice and disabling due to failure. * * @param listener The listener for the event. */ - public void addPropertyChangeListener(PropertyChangeListener listener) { + public static void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } @@ -139,13 +162,13 @@ public class CentralRepoDbManager { * This method removes a propert change listener. * @param listener The listener to remove. */ - public void removePropertyChangeListener(PropertyChangeListener listener) { + public static void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } - private CentralRepoDbChoice fromKey(String keyName) { + private static CentralRepoDbChoice fromKey(String keyName) { for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.values()) { if (dbChoice.getSettingKey().equalsIgnoreCase(keyName)) { return dbChoice; @@ -163,7 +186,7 @@ public class CentralRepoDbManager { * @return The CentralRepository object that will be used for connection. * @throws CentralRepoException */ - private CentralRepository obtainCentralRepository() throws CentralRepoException { + private static CentralRepository obtainCentralRepository() throws CentralRepoException { //get connection try { return CentralRepository.getInstance(); @@ -184,7 +207,7 @@ public class CentralRepoDbManager { * @return The lock if acquired. * @throws CentralRepoException */ - private CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { + private static CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { try { // This may return null if locking isn't supported, which is fine. It will // throw an exception if locking is supported but we can't get the lock @@ -208,7 +231,7 @@ public class CentralRepoDbManager { * @param lock The acquired lock. * @throws CentralRepoException */ - private void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { + private static void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { try { db.upgradeSchema(); } catch (CentralRepoException ex) { @@ -239,7 +262,7 @@ public class CentralRepoDbManager { * settings will be cleared. */ @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) - public void upgradeDatabase() throws CentralRepoException { + public static void upgradeDatabase() throws CentralRepoException { if (!CentralRepository.isEnabled()) { return; } @@ -256,7 +279,7 @@ public class CentralRepoDbManager { } } - private void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { + private static void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { // Disable the central repo and clear the current settings. try { if (null != CentralRepository.getInstance()) { @@ -265,7 +288,7 @@ public class CentralRepoDbManager { } catch (CentralRepoException ex2) { logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } - saveDbChoice(CentralRepoDbChoice.DISABLED); + saveDbChoice(CentralRepoDbChoice.DISABLED, false); if (innerException == null) { throw new CentralRepoException(message, desc); } else { @@ -275,6 +298,21 @@ public class CentralRepoDbManager { + private DatabaseTestResult testingStatus; + private CentralRepoDbChoice selectedDbChoice; + + private final PostgresCentralRepoSettings dbSettingsPostgres; + private final PostgresCentralRepoSettings dbSettingsMultiUser; + private final SqliteCentralRepoSettings dbSettingsSqlite; + + private boolean configurationChanged = false; + + public CentralRepoDbManager() { + selectedDbChoice = getSavedDbChoice(); + dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER); + dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); + dbSettingsSqlite = new SqliteCentralRepoSettings(); + } /** @@ -327,28 +365,30 @@ public class CentralRepoDbManager { saveNewCentralRepo(); } - private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { - return getSettings(getSelectedDbChoice()); + /** + * This method returns if changes to the central repository configuration were + * successfully applied. + * + * @return Returns true if the database configuration was successfully changed false + * if it was not. + */ + public boolean wasConfigurationChanged() { + return configurationChanged; } - private CentralRepoDbConnectivityManager getSavedSettings() throws CentralRepoException { - return getSettings(getSavedDbChoice()); - } - - private CentralRepoDbConnectivityManager getSettings(CentralRepoDbChoice dbChoice) throws CentralRepoException { - if (dbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) return dbSettingsMultiUser; - if (dbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return dbSettingsPostgres; - if (dbChoice == CentralRepoDbChoice.SQLITE) + if (selectedDbChoice == CentralRepoDbChoice.SQLITE) return dbSettingsSqlite; - if (dbChoice == CentralRepoDbChoice.DISABLED) + if (selectedDbChoice == CentralRepoDbChoice.DISABLED) return null; - throw new CentralRepoException("Unknown database type: " + dbChoice); + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } - - + private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsMultiUser); @@ -405,7 +445,7 @@ public class CentralRepoDbManager { } /** - * This method saves a new central repository based on current selected settings. + * This method saves a new central repository based on current settings. */ @NbBundle.Messages({"CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database."}) public void saveNewCentralRepo() throws CentralRepoException { @@ -444,6 +484,7 @@ public class CentralRepoDbManager { try { logger.info("Saving central repo settings for db: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); + configurationChanged = true; } catch (CentralRepoException ex) { logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS return; @@ -475,14 +516,6 @@ public class CentralRepoDbManager { public void clearStatus() { testingStatus = DatabaseTestResult.UNTESTED; } - - /** - * Resets selected db choice to currently saved choice. - */ - public void resetSelectedDbChoice() { - setSelctedDbChoice(getSavedDbChoice()); - } - /** * This method sets the currently selected database choice and sets the testing status to untested. @@ -522,38 +555,19 @@ public class CentralRepoDbManager { } /** - * This method tests the current selected (not necessarily saved) database settings to see if a valid connection can be made. + * This method tests the current database settings to see if a valid connection can be made. * @return The result of testing the connection. */ public DatabaseTestResult testStatus() { - CentralRepoDbConnectivityManager manager = null; try { - manager = getSelectedSettings(); + CentralRepoDbConnectivityManager manager = getSelectedSettings(); + if (manager != null) + testingStatus = manager.testStatus(); } catch (CentralRepoException e) { logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); } - return testStatus(manager); - } - - - public DatabaseTestResult testSavedStatus() { - CentralRepoDbConnectivityManager manager = null; - try { - manager = getSavedSettings(); - } - catch (CentralRepoException e) { - logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); - } - - return testStatus(manager); - } - - private DatabaseTestResult testStatus(CentralRepoDbConnectivityManager manager) { - if (manager != null) - testingStatus = manager.testStatus(); - return testingStatus; } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index 944703f532..0acfd34ea5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -39,7 +39,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { try (Statement statement = connection.createStatement();) { - CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); + CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); // Create account_types and accounts tables which are referred by X_instances tables statement.execute(RdbmsCentralRepoFactory.getCreateAccountTypesTableStatement(selectedPlatform)); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 5106f133b4..6a4a138cfb 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -42,7 +42,7 @@ public interface CentralRepository { CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.DISABLED; if (CentralRepoDbUtil.allowUseOfCentralRepository()) { - selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); + selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); } switch (selectedPlatform) { case POSTGRESQL: @@ -93,7 +93,7 @@ public interface CentralRepository { */ static boolean isEnabled() { return CentralRepoDbUtil.allowUseOfCentralRepository() - && CentralRepoDbManager.getInstance().getSavedDbChoice() != CentralRepoDbChoice.DISABLED; + && CentralRepoDbManager.getSavedDbChoice() != CentralRepoDbChoice.DISABLED; } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java index 4a02c50569..8b442efc24 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java @@ -69,7 +69,7 @@ public class CentralRepositoryService implements AutopsyService { */ private void updateSchema() throws AutopsyServiceException { try { - CentralRepoDbManager.getInstance().upgradeDatabase(); + CentralRepoDbManager.upgradeDatabase(); } catch (CentralRepoException ex) { throw new AutopsyServiceException("Failed to update the Central Repository schema", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 68765cf259..165d4ca6e0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -46,7 +46,7 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv private PostgresConnectionSettings connSettings; private static PostgresSettingsLoader getLoaderFromSaved() throws CentralRepoException { - CentralRepoDbChoice choice = CentralRepoDbManager.getInstance().getSavedDbChoice(); + CentralRepoDbChoice choice = CentralRepoDbManager.getSavedDbChoice(); if (choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER; else if (choice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index c0642bc59f..256e5407c9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -3528,7 +3528,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { conn = connect(false); conn.setAutoCommit(false); statement = conn.createStatement(); - selectedPlatform = CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform(); + selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); int minorVersion = 0; String minorVersionStr = null; resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "'"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index ff64ae56f7..da58e8936b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -181,7 +181,8 @@ public class Installer extends ModuleInstall { * repository. */ private void setupDefaultSqliteCentralRepo() throws CentralRepoException { - CentralRepoDbManager.getInstance().setupDefaultSqliteDb(); + CentralRepoDbManager manager = new CentralRepoDbManager(); + manager.setupDefaultSqliteDb(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index db44477eb2..1f7472d330 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -275,7 +275,7 @@ final class CentralRepoIngestModule implements FileIngestModule { // Don't allow sqlite central repo databases to be used for multi user cases if ((autopsyCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) - && (CentralRepoDbManager.getInstance().getSavedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE)) { + && (CentralRepoDbManager.getSavedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE)) { 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 } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index d6d620bb6d..4851afd2a2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -86,7 +86,7 @@ public class EamDbSettingsDialog extends JDialog { private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; - private final CentralRepoDbManager manager = CentralRepoDbManager.getInstance(); + private final CentralRepoDbManager manager = new CentralRepoDbManager(); private final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); public EamDbSettingsDialog() { @@ -586,9 +586,20 @@ public class EamDbSettingsDialog extends JDialog { parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return true; } + + + /** + * This method returns if changes to the central repository configuration were + * successfully applied. + * + * @return True if the database configuration was successfully changed; false + * if it was not. + */ + public boolean wasConfigurationChanged() { + return manager.wasConfigurationChanged(); + } private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed - manager.resetSelectedDbChoice(); dispose(); }//GEN-LAST:event_bnCancelActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 1dfe191420..86ab06dc0c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -253,6 +253,12 @@ + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 1fbe5e0b31..edee10f795 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -61,7 +61,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private final IngestJobEventPropertyChangeListener ingestJobEventListener; - private final CentralRepoDbManager manager; private final ImageIcon goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); private final ImageIcon badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); @@ -71,10 +70,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i */ public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - manager = CentralRepoDbManager.getInstance(); - + // listen for change events in currently saved choice - manager.addPropertyChangeListener((PropertyChangeEvent evt) -> { + CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> { //ingestStateUpdated(Case.isCaseOpen()); load(); // reload db settings content and update buttons @@ -111,10 +109,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * * @return True if there was a change. */ - private static void invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { + private static boolean invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { EamDbSettingsDialog dialog = (initialSelection != null) - ? new EamDbSettingsDialog(initialSelection) - : new EamDbSettingsDialog(); + ? new EamDbSettingsDialog(initialSelection) + : new EamDbSettingsDialog(); + return dialog.wasConfigurationChanged(); } /** @@ -136,9 +135,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { - CentralRepoDbManager manager = CentralRepoDbManager.getInstance(); boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository(); - boolean crMultiUser = manager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; + boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { @@ -154,8 +152,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // setup database for CR CentralRepoDbUtil.setUseCentralRepo(true); - manager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - checkStatusAndCreateDb(manager, parent); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); + checkStatusAndCreateDb(parent); } }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected @@ -166,7 +164,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && // central repo either enabled or was disabled due to error else if (muPreviouslySelected && muCurrentlySelected && crEnabled && crMultiUser) { - checkStatusAndCreateDb(manager, parent); + checkStatusAndCreateDb(parent); } } @@ -176,9 +174,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * database if cr database is absent. * @param parent the parent component to which the dialogs will be associated. */ - private static void checkStatusAndCreateDb(CentralRepoDbManager manager, Component parent) { + private static void checkStatusAndCreateDb(Component parent) { SwingUtilities.invokeLater(() -> { - EamDbSettingsDialog.testStatusAndCreate(parent, manager); + EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); }); } @@ -231,6 +229,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.", }) private boolean testCurrentConfiguration() { + CentralRepoDbManager manager = new CentralRepoDbManager(); DatabaseTestResult testResult = manager.testStatus(); // if database doesn't exist, prompt user to create database if (testResult == DatabaseTestResult.DB_DOES_NOT_EXIST) { @@ -251,7 +250,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } private boolean showStatusOkay() { - return setStatus(goodIcon, null); + return setStatus(goodIcon, " "); } private boolean showStatusFail(String message) { @@ -351,6 +350,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i testStatusLabel.setFont(testStatusLabel.getFont().deriveFont(testStatusLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(testStatusLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.text")); // NOI18N testStatusLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.toolTipText")); // NOI18N + testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 40)); + testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 16)); javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration); pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout); @@ -644,7 +645,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i public void load() { tbOops.setText(""); enableButtonSubComponents(false); - CentralRepoDbChoice selectedChoice = manager.getSavedDbChoice(); + CentralRepoDbChoice selectedChoice = CentralRepoDbManager.getSavedDbChoice(); cbUseCentralRepo.setSelected(CentralRepoDbUtil.allowUseOfCentralRepository()); // NON-NLS lbDbPlatformValue.setText(selectedChoice.getTitle()); From e8c767f9b6aa4b27cea489cd4f46e9c6d5603d7f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 11:41:58 -0400 Subject: [PATCH 08/49] fix for loading issue --- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index edee10f795..c354251850 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -615,7 +615,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); - invokeCrChoice(this, null); + boolean changed = invokeCrChoice(this, null); + if (changed) { + load(); // reload db settings content and update buttons + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_bnDbConfigureActionPerformed private void manageOrganizationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageOrganizationButtonActionPerformed From 9f43d666e8e9cf980c116432e86e98ad7062a51c Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 12:58:57 -0400 Subject: [PATCH 09/49] property change support listeners --- .../optionspanel/GlobalSettingsPanel.form | 22 ++++--- .../optionspanel/GlobalSettingsPanel.java | 65 +++++++++++++------ 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 86ab06dc0c..d9d5b14296 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -155,9 +155,9 @@ - - - + + + @@ -181,11 +181,13 @@ - - - - - + + + + + + + @@ -254,10 +256,10 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index c354251850..2ec00492c7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -42,6 +42,8 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; +import java.awt.Dimension; +import java.beans.PropertyChangeSupport; import java.util.logging.Level; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; @@ -60,35 +62,54 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName()); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); + // this allows property change events to be fired at a static level but listened to by instances + private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(GlobalSettingsPanel.class); + + // tracks the last known instance property change listener so that only one GlobalSettingsPanel is listening for events + private static PropertyChangeListener lastRegistered = null; + private final IngestJobEventPropertyChangeListener ingestJobEventListener; private final ImageIcon goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); private final ImageIcon badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); + /** * Creates new form EamOptionsPanel */ public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - - // listen for change events in currently saved choice - CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> { - //ingestStateUpdated(Case.isCaseOpen()); - - load(); // reload db settings content and update buttons - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - clearStatus(); - }); - initComponents(); customizeComponents(); + setupSettingsChangeListeners(); addIngestJobEventsListener(); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { //disable when case is open, enable when case is closed ingestStateUpdated(evt.getNewValue() != null); }); } + + + private void setupSettingsChangeListeners() { + // listen for change events in currently saved choice + if (lastRegistered != null) { + CentralRepoDbManager.removePropertyChangeListener(lastRegistered); + GlobalSettingsPanel.propertyChangeSupport.removePropertyChangeListener(lastRegistered); + } + + lastRegistered = this::onSettingsChange; + CentralRepoDbManager.addPropertyChangeListener(lastRegistered); + GlobalSettingsPanel.propertyChangeSupport.addPropertyChangeListener(lastRegistered); + } + + + private void onSettingsChange(PropertyChangeEvent evt) { + ingestStateUpdated(Case.isCaseOpen()); + clearStatus(); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + private void customizeComponents() { setName(NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title")); } @@ -164,6 +185,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && // central repo either enabled or was disabled due to error else if (muPreviouslySelected && muCurrentlySelected && crEnabled && crMultiUser) { + GlobalSettingsPanel.propertyChangeSupport.firePropertyChange("multiuserSettingsChanged", null, null); checkStatusAndCreateDb(parent); } } @@ -258,7 +280,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } private void clearStatus() { - setStatus(null, null); + setStatus(null, " "); } private boolean setStatus(ImageIcon icon, String text) { @@ -350,8 +372,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i testStatusLabel.setFont(testStatusLabel.getFont().deriveFont(testStatusLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(testStatusLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.text")); // NOI18N testStatusLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.toolTipText")); // NOI18N - testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 40)); - testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 16)); + testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 32)); + testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 32)); javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration); pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout); @@ -374,9 +396,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(bnDbConfigure) .addGap(18, 18, 18) .addComponent(bnTestConfigure) - .addGap(18, 18, 18) - .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 805, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(19, Short.MAX_VALUE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 416, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(420, Short.MAX_VALUE)))) ); pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -393,11 +415,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnDbConfigure) - .addComponent(bnTestConfigure) - .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnDbConfigure) + .addComponent(bnTestConfigure)) + .addComponent(testStatusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(8, 8, 8)) ); From 92205e1aab326d4201072bc2c104ba9ebcff5e1c Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 14:20:54 -0400 Subject: [PATCH 10/49] updated layout --- .../optionspanel/GlobalSettingsPanel.form | 23 ++++++++++--------- .../optionspanel/GlobalSettingsPanel.java | 20 ++++++++-------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index d9d5b14296..7fafd68c22 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -156,8 +156,8 @@ - - + + @@ -181,13 +181,11 @@ - - - - - - - + + + + + @@ -249,6 +247,9 @@ + + + @@ -256,10 +257,10 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 2ec00492c7..ee22b5c966 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -370,10 +370,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i }); testStatusLabel.setFont(testStatusLabel.getFont().deriveFont(testStatusLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + testStatusLabel.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(testStatusLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.text")); // NOI18N testStatusLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.toolTipText")); // NOI18N - testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 32)); - testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 32)); + testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 16)); + testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 16)); javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration); pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout); @@ -397,8 +398,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGap(18, 18, 18) .addComponent(bnTestConfigure) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 416, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(420, Short.MAX_VALUE)))) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 671, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(165, Short.MAX_VALUE)))) ); pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -415,12 +416,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) - .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnDbConfigure) - .addComponent(bnTestConfigure)) - .addComponent(testStatusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 10, Short.MAX_VALUE) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnDbConfigure) + .addComponent(bnTestConfigure) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(8, 8, 8)) ); From c7dd2be6e056bfd44f7e257c4bc869d1df114ed5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 14:22:04 -0400 Subject: [PATCH 11/49] dialog message changes --- .../centralrepository/optionspanel/EamDbSettingsDialog.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 4851afd2a2..a16b7f5d87 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -158,11 +158,11 @@ public class EamDbSettingsDialog extends JDialog { * @param dialog If non-null value, validates settings and updates 'okay' button enabled state. * @return Whether or not the ultimate status after prompts is okay to continue. */ - @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", + @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database", "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", - "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", + "EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist", "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed", "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again.", "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", From 244b996cdc2ffe71f71e34edae03b736487a38b3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 15:58:20 -0400 Subject: [PATCH 12/49] fix to deal with merge conflict --- .../casemodule/Bundle.properties-MERGED | 2 +- .../optionspanel/Bundle.properties-MERGED | 13 ++++++++++--- .../optionspanel/GlobalSettingsPanel.form | 17 ++++++++++------- .../optionspanel/GlobalSettingsPanel.java | 14 ++++++++------ .../autopsy/core/Bundle.properties-MERGED | 8 +++++++- .../autopsy/coreutils/Bundle.properties-MERGED | 4 +++- .../directorytree/Bundle.properties-MERGED | 6 +++--- .../filesearch/Bundle.properties-MERGED | 10 +++++----- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../livetriage/Bundle.properties-MERGED | 4 ++-- .../Bundle.properties-MERGED | 4 ++-- .../Bundle.properties-MERGED | 8 ++++++-- .../modules/exif/Bundle.properties-MERGED | 4 +++- .../fileextmismatch/Bundle.properties-MERGED | 18 +++++++++--------- .../filetypeid/Bundle.properties-MERGED | 6 +++--- .../hashdatabase/Bundle.properties-MERGED | 14 ++++++++------ .../interestingitems/Bundle.properties-MERGED | 18 +++++++++--------- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +++--- .../keywordsearch/Bundle.properties-MERGED | 2 +- .../recentactivity/Bundle.properties-MERGED | 11 +++-------- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 23 files changed, 103 insertions(+), 80 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index b56e46b377..b062dffebd 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -186,7 +186,6 @@ NewCaseVisualPanel1.caseNameLabel.text_1=Case Name: NewCaseVisualPanel1.caseDirLabel.text=Base Directory: NewCaseVisualPanel1.caseDirBrowseButton.text=Browse NewCaseVisualPanel1.caseNameTextField.text_1= -NewCaseVisualPanel1.jLabel2.text_1=Case data will be stored in the following directory: NewCaseVisualPanel1.caseParentDirTextField.text= NewCaseVisualPanel1.caseDirTextField.text_1= CueBannerPanel.autopsyLogo.text= @@ -467,3 +466,4 @@ UnpackagePortableCaseProgressDialog.okButton.text=OK UnpackagePortableCaseProgressDialog.resultLabel.text=resultLabel UnpackagePortableCaseDialog.extractLabel.text=Folder to extract to: UnpackagePortableCaseDialog.caseLabel.text=Portable Case: +NewCaseVisualPanel1.caseDataStoredLabel.text_1=Case data will be stored in the following directory: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 395330b4db..b9d0716154 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -13,14 +13,14 @@ EamDbSettingsDialog.lbDatabaseType.text=Database Type : EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time. EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database. EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable). -EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database +EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it? -EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist +EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again. EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again. EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again. -EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed +EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform. EamDbSettingsDialog.okButton.errorTitle.text=Restart Required. EamDbSettingsDialog.textPrompt.dbName=Database Name @@ -33,12 +33,16 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database. EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. +GlobalSettingsPanel.askForCentralRepoDbChoice.customPostgrestChoice.text=Configure PostgreSQL +GlobalSettingsPanel.askForCentralRepoDbChoice.disableChoice.text=Disable Central Repository +GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database. GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database. GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository? +GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist. GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. ManageCasesDialog.title.text=Manage Cases @@ -147,3 +151,6 @@ ManageCasesDialog.closeButton.text=Close ManageCasesDialog.notesLabel.text=Notes: ManageCasesDialog.dataSourcesLabel.text=Data Sources: ManageCasesDialog.caseInfoLabel.text=Case Info: +GlobalSettingsPanel.bnTestConfigure.text=Test +GlobalSettingsPanel.testStatusLabel.toolTipText= +GlobalSettingsPanel.testStatusLabel.text= diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index f526ad1a3c..c7fd365389 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -61,7 +61,7 @@ - + @@ -147,7 +147,10 @@ - + + + + @@ -155,8 +158,8 @@ - - + + @@ -180,11 +183,11 @@ - + - + @@ -298,7 +301,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index bb0912d190..baa24c787b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -392,14 +392,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnDatabaseConfigurationLayout.createSequentialGroup() + .addComponent(lbDbLocationValue, javax.swing.GroupLayout.DEFAULT_SIZE, 255, Short.MAX_VALUE) + .addGap(681, 681, 681)))) .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addComponent(bnDbConfigure) .addGap(18, 18, 18) .addComponent(bnTestConfigure) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 671, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(165, Short.MAX_VALUE)))) + .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 675, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -416,11 +418,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 10, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnDbConfigure) .addComponent(bnTestConfigure) - .addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(8, 8, 8)) ); @@ -464,7 +466,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i pnCorrelationPropertiesLayout.setVerticalGroup( pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnCorrelationPropertiesLayout.createSequentialGroup() - .addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE) + .addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(bnManageTypes) .addGap(8, 8, 8)) diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index c84f1f1b86..0b16a9701f 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,7 +3,13 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=\ + This is the core Autopsy module.\n\n\ + The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ + The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ + The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ + This module should not be uninstalled - without it, Autopsy will not run.\n\n\ + For more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index 18e279dd2c..a0d535f8e6 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,7 +30,9 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ +{1}\n\ +Process Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED index 63b416b176..7e96d8fdaa 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED @@ -38,8 +38,6 @@ HINT_DirectoryTreeTopComponent=This is a DirectoryTree window OpenIDE-Module-Name=DirectoryTree FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset: FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type: -FileSystemDetailsPanel.jLabel2.text=bytes -FileSystemDetailsPanel.jLabel3.text=bytes FileSystemDetailsPanel.fsTypeValue.text=... FileSystemDetailsPanel.imgOffsetValue.text=... FileSystemDetailsPanel.volumeIDValue.text=... @@ -71,7 +69,6 @@ VolumeDetailsPanel.startLabel.text=Starting Sector: VolumeDetailsPanel.lengthLabel.text=Length in Sectors: VolumeDetailsPanel.descLabel.text=Description: VolumeDetailsPanel.flagsLabel.text=Flags: -VolumeDetailsPanel.jLabel1.text=General Volume Information VolumeDetailsPanel.OKButton.text=OK ImageDetailsPanel.imageInfoLabel.text=Image Information ImageDetailsPanel.imgNameLabel.text=Name: @@ -160,3 +157,6 @@ ExternalViewerGlobalSettingsPanel.jButton2.text=jButton2 ExternalViewerGlobalSettingsPanel.browseHxDDirectory.text=Browse ExternalViewerGlobalSettingsPanel.HxDLabel.text=HxD Editor Path: ExternalViewerGlobalSettingsPanel.ContentViewerExtensionLabel.text=Add content viewer extensions: +FileSystemDetailsPanel.bytesLabel1.text=bytes +FileSystemDetailsPanel.bytesLabel2.text=bytes +VolumeDetailsPanel.generalVolumeLabel.text=General Volume Information diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index c585d0edf5..b304bc1342 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,11 +14,9 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: -DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy -DateSearchPanel.jLabel2.text=*Empty fields mean "No Limit" DateSearchPanel.createdCheckBox.text=Created DateSearchPanel.accessedCheckBox.text=Accessed DateSearchPanel.changedCheckBox.text=Changed @@ -57,12 +55,11 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than SizeSearchPanel.sizeCompareComboBox.lessThan=less than -MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected FileSearchPanel.searchButton.text=Search MimeTypePanel.mimeTypeCheckBox.text=MIME Type: HashSearchPanel.md5CheckBox.text=MD5: @@ -72,3 +69,6 @@ DataSourcePanel.dataSourceCheckBox.label=Data Source: DataSourcePanel.dataSourceCheckBox.actionCommand=Data Source: DataSourcePanel.dataSourceCheckBox.text=Data Source: DataSourcePanel.dataSourceNoteLabel.text=*Note: Multiple data sources can be selected +DateSearchPanel.noLimitLabel.text=*Empty fields mean "No Limit" +DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy +MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 6be3e48e71..9e4f612b6b 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest= +gest IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED index e0a2ab0413..309a07d3da 100755 --- a/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED @@ -18,10 +18,10 @@ SelectDriveDialog.diskTable.column2.title=Disk Size SelectDriveDialog.errLabel.disksNotDetected.text=Disks were not detected. On some systems it requires admin privileges SelectDriveDialog.errLabel.disksNotDetected.toolTipText=Disks were not detected. SelectDriveDialog.lbSelectDrive.text=Select the drive to copy the application and script to: -SelectDriveDialog.jLabel1.text=Select drive to use for live triage (may take time to load): SelectDriveDialog.errorLabel.text=jLabel2 SelectDriveDialog.bnCancel.text=Cancel -SelectDriveDialog.jTextArea1.text=This feature copies the application and a batch file to a removable drive,\nallowing systems to be analyzed without installing the software or\nimaging the drives.\n\nTo analyze a system, insert the drive and run "RunFromUSB.bat" as\nadministrator, then select the "Local Disk" option on the Add Data Source\npanel. +SelectDriveDialog.descriptionTextArea.text=This feature copies the application and a batch file to a removable drive,\nallowing systems to be analyzed without installing the software or\nimaging the drives.\n\nTo analyze a system, insert the drive and run "RunFromUSB.bat" as\nadministrator, then select the "Local Disk" option on the Add Data Source\npanel. SelectDriveDialog.localDiskModel.loading.msg= SelectDriveDialog.localDiskModel.nodrives.msg=Executable could not be found +SelectDriveDialog.selectDriveLabel.text=Select drive to use for live triage (may take time to load): SelectDriveDialog.title=Create Live Triage Drive diff --git a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED index b006deb22d..e69126f939 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED @@ -45,6 +45,6 @@ DataSourceIntegrityIngestModule.shutDown.resultLi=
  • Result:{0}
  • DataSourceIntegrityIngestModule.shutDown.calcHashLi=
  • Calculated hash: {0}
  • DataSourceIntegrityIngestModule.shutDown.storedHashLi=
  • Stored hash: {0}
  • DataSourceIntegrityIngestSettingsPanel.computeHashesCheckbox.text=Calculate data source hashes if none are present -DataSourceIntegrityIngestSettingsPanel.jLabel1.text=Note that this module will not run on logical files -DataSourceIntegrityIngestSettingsPanel.jLabel3.text=Ingest Settings DataSourceIntegrityIngestSettingsPanel.verifyHashesCheckbox.text=Verify existing data source hashes +DataSourceIntegrityIngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings +DataSourceIntegrityIngestSettingsPanel.noteLabel.text=Note that this module will not run on logical files diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4729293fb9..4585d86449 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,7 +11,12 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=\ + Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ + Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ + If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ + The extracted files are navigable in the directory tree.\n\n\ + The module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -23,7 +28,6 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} -EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index 4915d5a124..f9a5a88b1b 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,7 +2,9 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=\ + Exif metadata ingest module. \n\n\ + The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index 5063bd55fa..cfaadf1635 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED index ccc55e18b0..ca866a4a13 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED @@ -51,7 +51,6 @@ FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=Load Failed FileTypeIdGlobalSettingsPanel.loadFileTypes.errorMessage=Failed to load existing file type definitions. FileTypeIdGlobalSettingsPanel.saveFileTypes.errorMessage=Failed to save file type definitions. FileTypeIdGlobalSettingsPanel.newTypeButton.text=New Type -FileTypeIdGlobalSettingsPanel.jLabel2.text=Custom MIME Types: FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. AddFileTypeSignaturePanel.offsetLabel.text=Byte Offset AddFileTypeSignaturePanel.signatureTextField.text= @@ -60,7 +59,6 @@ AddFileTypeSignaturePanel.signatureLabel.text=Signature AddFileTypeSignaturePanel.hexPrefixLabel.text=0x AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetTextField.text= -FileTypeIdGlobalSettingsPanel.jLabel1.text=Signatures FileTypeIdGlobalSettingsPanel.editTypeButton.text=Edit Type AddFileTypePanel.mimeTypeTextField.text= AddFileTypePanel.mimeTypeLabel.text=MIME Type @@ -72,4 +70,6 @@ AddFileTypePanel.postHitCheckBox.text=Alert as an "Interesting File" when found AddFileTypePanel.setNameLabel.text=Set Name AddFileTypePanel.setNameTextField.text= FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text=Cannot make changes to file type definitions when ingest is running! -FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here. +FileTypeIdGlobalSettingsPanel.descriptionLabel.text=Autopsy can automatically detect many file types. Add your custom file types here. +FileTypeIdGlobalSettingsPanel.customTypesLabel.text=Custom MIME Types: +FileTypeIdGlobalSettingsPanel.signaturesLabel.text=Signatures diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 44057d0016..0f4db124af 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,7 +49,10 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=\ + Hash Set ingest module. \n\n\ + The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ + The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -178,7 +181,10 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ +The generated index will be left unusable. If you choose to continue,\n\ + please delete the corresponding -md5.idx file in the hash folder.\n\ + Exit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} @@ -205,10 +211,6 @@ AddContentToHashDbAction.singleSelectionNameEmpty=Add File to Hash Set (Empty Fi AddContentToHashDbAction.multipleSelectionNameEmpty=Add Files to Hash Set (Empty File) HashDbManager.ingestRunningExceptionMsg=Ingest is ongoing; this service will be unavailable until it finishes. HashDbManager.saveErrorExceptionMsg=Error saving hash configuration -HashLookupSettingsPanel.jButton3.text=Import Hash Set -HashLookupSettingsPanel.jLabel6.text=Type: -HashLookupSettingsPanel.jLabel4.text=Location: -HashLookupSettingsPanel.jLabel2.text=Name: HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=Calculate MD5 even if no hash set is selected HashLookupModuleSettingsPanel.knownHashDbsLabel.text=Select known hash sets to use: HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=Select notable hash sets to use: diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 31a0690b82..3c275ee9cb 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names @@ -109,21 +109,14 @@ FilesSetDefsPanel.ingest.deleteSetButton.text=Delete Filter FilesSetDefsPanel.interesting.jLabel6.text=Set Details FilesSetDefsPanel.ingest.jLabel6.text=Filter Details FilesSetDefsPanel.newRuleButton.text=New Rule -FilesSetDefsPanel.jLabel8.text=File Size: -FilesSetDefsPanel.jLabel7.text=MIME Type: FilesSetDefsPanel.rulePathConditionRegexCheckBox.text=Regex -FilesSetDefsPanel.jLabel4.text=Path Substring: -FilesSetDefsPanel.jLabel1.text=Rule Details FilesSetDefsPanel.dirsRadioButton.text=Directories -FilesSetDefsPanel.jLabel2.text=File Type: FilesSetDefsPanel.deleteRuleButton.text=Delete Rule FilesSetDefsPanel.fileNameRegexCheckbox.text=Substring / Regex FilesSetDefsPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files FilesSetDefsPanel.rulePathConditionTextField.text= FilesSetDefsPanel.fileNameRadioButton.text=Full Name -FilesSetDefsPanel.jLabel5.text=Description: FilesSetDefsPanel.fileNameTextField.text= -FilesSetDefsPanel.jLabel3.text=Name: FilesSetDefsPanel.fileNameExtensionRadioButton.text=Extension Only FilesSetDefsPanel.rulesListLabel.text=Rules: FilesSetDefsPanel.editRuleButton.text=Edit Rule @@ -140,3 +133,10 @@ FilesSetDefsPanel.modifiedDateLabel.text=Modified Within: FilesSetDefsPanel.daysIncludedTextField.text= FilesSetDefsPanel.daysIncludedLabel.text=day(s) FilesSetRulePanel.daysIncludedLabel.text=day(s) +FilesSetDefsPanel.nameLabel.text=Name: +FilesSetDefsPanel.descriptionLabel.text=Description: +FilesSetDefsPanel.fileTypeLabel.text=File Type: +FilesSetDefsPanel.ruleLabel.text=Rule Details +FilesSetDefsPanel.pathLabel.text=Path Substring: +FilesSetDefsPanel.mimeTypeLabel.text=MIME Type: +FilesSetDefsPanel.fileSizeLabel.text=File Size: diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 2dc971a40d..87dacfc16c 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 0be7595111..32f6867f0c 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 9aeeabc046..92c55b614f 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -36,7 +36,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found KeywordSearchResultFactory.query.exception.msg=Could not perform the query OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. +OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Name=KeywordSearch OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 18deff87f4..ebdce8a327 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,7 +1,6 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: -Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -14,9 +13,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive +# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity -Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -25,11 +24,6 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file -ExtractIE.getBookmark.ere.noSpace=RecentActivity -ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. -ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. -ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. -Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -96,7 +90,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -198,6 +192,7 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. +# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index b20ccf5912..199e018ea8 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Tue, 12 Nov 2019 17:21:46 -0500 +#Wed, 01 Apr 2020 15:51:37 -0400 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.13.0 +currentVersion=Autopsy 4.14.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 998d3f715c..9368d6b951 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Tue, 12 Nov 2019 17:21:46 -0500 -CTL_MainWindow_Title=Autopsy 4.13.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 +#Wed, 01 Apr 2020 15:51:37 -0400 +CTL_MainWindow_Title=Autopsy 4.14.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 From 46f77cf8ba2a250475548da0917e12e131477304 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 1 Apr 2020 16:00:52 -0400 Subject: [PATCH 13/49] bundle fixes --- .../casemodule/Bundle.properties-MERGED | 2 +- .../autopsy/core/Bundle.properties-MERGED | 8 +------- .../corecomponents/Bundle.properties-MERGED | 12 ++++++------ .../autopsy/coreutils/Bundle.properties-MERGED | 4 +--- .../directorytree/Bundle.properties-MERGED | 6 +++--- .../filesearch/Bundle.properties-MERGED | 10 +++++----- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../livetriage/Bundle.properties-MERGED | 4 ++-- .../Bundle.properties-MERGED | 4 ++-- .../Bundle.properties-MERGED | 8 ++------ .../modules/exif/Bundle.properties-MERGED | 4 +--- .../fileextmismatch/Bundle.properties-MERGED | 18 +++++++++--------- .../filetypeid/Bundle.properties-MERGED | 6 +++--- .../hashdatabase/Bundle.properties-MERGED | 14 ++++++-------- .../interestingitems/Bundle.properties-MERGED | 18 +++++++++--------- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +++--- .../keywordsearch/Bundle.properties-MERGED | 2 +- .../recentactivity/Bundle.properties-MERGED | 11 ++++++++--- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 21 files changed, 70 insertions(+), 81 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index b062dffebd..b56e46b377 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -186,6 +186,7 @@ NewCaseVisualPanel1.caseNameLabel.text_1=Case Name: NewCaseVisualPanel1.caseDirLabel.text=Base Directory: NewCaseVisualPanel1.caseDirBrowseButton.text=Browse NewCaseVisualPanel1.caseNameTextField.text_1= +NewCaseVisualPanel1.jLabel2.text_1=Case data will be stored in the following directory: NewCaseVisualPanel1.caseParentDirTextField.text= NewCaseVisualPanel1.caseDirTextField.text_1= CueBannerPanel.autopsyLogo.text= @@ -466,4 +467,3 @@ UnpackagePortableCaseProgressDialog.okButton.text=OK UnpackagePortableCaseProgressDialog.resultLabel.text=resultLabel UnpackagePortableCaseDialog.extractLabel.text=Folder to extract to: UnpackagePortableCaseDialog.caseLabel.text=Portable Case: -NewCaseVisualPanel1.caseDataStoredLabel.text_1=Case data will be stored in the following directory: diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index 0b16a9701f..c84f1f1b86 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,13 +3,7 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=\ - This is the core Autopsy module.\n\n\ - The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ - The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ - The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ - This module should not be uninstalled - without it, Autopsy will not run.\n\n\ - For more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index 544cfa63c0..f252420726 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
    \n Product Version: {0} ({9})
    Sleuth Kit Version: {7}
    Netbeans RCP Build: {8}
    Java: {1}; {2}
    System: {3}; {4}; {5}
    Userdir: {6}
    +LBL_Description=
    \n Product Version: {0} ({9})
    Sleuth Kit Version: {7}
    Netbeans RCP Build: {8}
    Java: {1}; {2}
    System: {3}; {4}; {5}
    Userdir: {6}
    Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
    Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
    Copyright © 2003-2018.
    +LBL_Copyright=
    Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
    Copyright © 2003-2018.
    SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ \ \ +DataResultViewerThumbnail.filePathLabel.text=\ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel @@ -129,9 +129,9 @@ DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails: {0} AboutWindowPanel.actVerboseLogging.text=Activate verbose logging OptionsCategory_Name_Multi_User_Settings=Multi-User OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings -MultiUserSettingsPanel.lbSolrSettings.text=Solr Server Settings +MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings MultiUserSettingsPanel.cbEnableMultiUser.text=Enable multi-user cases -MultiUserSettingsPanel.lbDatabaseSettings.text=Database Server Settings +MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values MultiUserSettingsPanel.nonWindowsOs.msg=Multi-user cases are only available on Windows platforms MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number @@ -159,7 +159,7 @@ MultiUserSettingsPanel.tbSolrHostname.toolTipText=Hostname or IP Address MultiUserSettingsPanel.tbSolrPort.toolTipText=Port Number MultiUserSettingsPanel.lbTestMessageService.text= MultiUserSettingsPanel.bnTestMessageService.text=Test -MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Server Settings +MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Service Settings MultiUserSettingsPanel.tbMsgPort.toolTipText=Port Number MultiUserSettingsPanel.tbMsgPort.text= MultiUserSettingsPanel.tbMsgUsername.toolTipText=User Name (optional) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index a0d535f8e6..18e279dd2c 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,9 +30,7 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ -{1}\n\ -Process Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED index 7e96d8fdaa..63b416b176 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties-MERGED @@ -38,6 +38,8 @@ HINT_DirectoryTreeTopComponent=This is a DirectoryTree window OpenIDE-Module-Name=DirectoryTree FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset: FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type: +FileSystemDetailsPanel.jLabel2.text=bytes +FileSystemDetailsPanel.jLabel3.text=bytes FileSystemDetailsPanel.fsTypeValue.text=... FileSystemDetailsPanel.imgOffsetValue.text=... FileSystemDetailsPanel.volumeIDValue.text=... @@ -69,6 +71,7 @@ VolumeDetailsPanel.startLabel.text=Starting Sector: VolumeDetailsPanel.lengthLabel.text=Length in Sectors: VolumeDetailsPanel.descLabel.text=Description: VolumeDetailsPanel.flagsLabel.text=Flags: +VolumeDetailsPanel.jLabel1.text=General Volume Information VolumeDetailsPanel.OKButton.text=OK ImageDetailsPanel.imageInfoLabel.text=Image Information ImageDetailsPanel.imgNameLabel.text=Name: @@ -157,6 +160,3 @@ ExternalViewerGlobalSettingsPanel.jButton2.text=jButton2 ExternalViewerGlobalSettingsPanel.browseHxDDirectory.text=Browse ExternalViewerGlobalSettingsPanel.HxDLabel.text=HxD Editor Path: ExternalViewerGlobalSettingsPanel.ContentViewerExtensionLabel.text=Add content viewer extensions: -FileSystemDetailsPanel.bytesLabel1.text=bytes -FileSystemDetailsPanel.bytesLabel2.text=bytes -VolumeDetailsPanel.generalVolumeLabel.text=General Volume Information diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index b304bc1342..c585d0edf5 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,9 +14,11 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: +DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy +DateSearchPanel.jLabel2.text=*Empty fields mean "No Limit" DateSearchPanel.createdCheckBox.text=Created DateSearchPanel.accessedCheckBox.text=Accessed DateSearchPanel.changedCheckBox.text=Changed @@ -55,11 +57,12 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than SizeSearchPanel.sizeCompareComboBox.lessThan=less than +MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected FileSearchPanel.searchButton.text=Search MimeTypePanel.mimeTypeCheckBox.text=MIME Type: HashSearchPanel.md5CheckBox.text=MD5: @@ -69,6 +72,3 @@ DataSourcePanel.dataSourceCheckBox.label=Data Source: DataSourcePanel.dataSourceCheckBox.actionCommand=Data Source: DataSourcePanel.dataSourceCheckBox.text=Data Source: DataSourcePanel.dataSourceNoteLabel.text=*Note: Multiple data sources can be selected -DateSearchPanel.noLimitLabel.text=*Empty fields mean "No Limit" -DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy -MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 9e4f612b6b..6be3e48e71 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest +gest= IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED index 309a07d3da..e0a2ab0413 100755 --- a/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/livetriage/Bundle.properties-MERGED @@ -18,10 +18,10 @@ SelectDriveDialog.diskTable.column2.title=Disk Size SelectDriveDialog.errLabel.disksNotDetected.text=Disks were not detected. On some systems it requires admin privileges SelectDriveDialog.errLabel.disksNotDetected.toolTipText=Disks were not detected. SelectDriveDialog.lbSelectDrive.text=Select the drive to copy the application and script to: +SelectDriveDialog.jLabel1.text=Select drive to use for live triage (may take time to load): SelectDriveDialog.errorLabel.text=jLabel2 SelectDriveDialog.bnCancel.text=Cancel -SelectDriveDialog.descriptionTextArea.text=This feature copies the application and a batch file to a removable drive,\nallowing systems to be analyzed without installing the software or\nimaging the drives.\n\nTo analyze a system, insert the drive and run "RunFromUSB.bat" as\nadministrator, then select the "Local Disk" option on the Add Data Source\npanel. +SelectDriveDialog.jTextArea1.text=This feature copies the application and a batch file to a removable drive,\nallowing systems to be analyzed without installing the software or\nimaging the drives.\n\nTo analyze a system, insert the drive and run "RunFromUSB.bat" as\nadministrator, then select the "Local Disk" option on the Add Data Source\npanel. SelectDriveDialog.localDiskModel.loading.msg= SelectDriveDialog.localDiskModel.nodrives.msg=Executable could not be found -SelectDriveDialog.selectDriveLabel.text=Select drive to use for live triage (may take time to load): SelectDriveDialog.title=Create Live Triage Drive diff --git a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED index e69126f939..b006deb22d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/Bundle.properties-MERGED @@ -45,6 +45,6 @@ DataSourceIntegrityIngestModule.shutDown.resultLi=
  • Result:{0}
  • DataSourceIntegrityIngestModule.shutDown.calcHashLi=
  • Calculated hash: {0}
  • DataSourceIntegrityIngestModule.shutDown.storedHashLi=
  • Stored hash: {0}
  • DataSourceIntegrityIngestSettingsPanel.computeHashesCheckbox.text=Calculate data source hashes if none are present +DataSourceIntegrityIngestSettingsPanel.jLabel1.text=Note that this module will not run on logical files +DataSourceIntegrityIngestSettingsPanel.jLabel3.text=Ingest Settings DataSourceIntegrityIngestSettingsPanel.verifyHashesCheckbox.text=Verify existing data source hashes -DataSourceIntegrityIngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings -DataSourceIntegrityIngestSettingsPanel.noteLabel.text=Note that this module will not run on logical files diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4585d86449..4729293fb9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,12 +11,7 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ - Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ - If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ - The extracted files are navigable in the directory tree.\n\n\ - The module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -28,6 +23,7 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} +EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index f9a5a88b1b..4915d5a124 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,9 +2,7 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Exif metadata ingest module. \n\n\ - The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index cfaadf1635..5063bd55fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED index ca866a4a13..ccc55e18b0 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties-MERGED @@ -51,6 +51,7 @@ FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=Load Failed FileTypeIdGlobalSettingsPanel.loadFileTypes.errorMessage=Failed to load existing file type definitions. FileTypeIdGlobalSettingsPanel.saveFileTypes.errorMessage=Failed to save file type definitions. FileTypeIdGlobalSettingsPanel.newTypeButton.text=New Type +FileTypeIdGlobalSettingsPanel.jLabel2.text=Custom MIME Types: FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. AddFileTypeSignaturePanel.offsetLabel.text=Byte Offset AddFileTypeSignaturePanel.signatureTextField.text= @@ -59,6 +60,7 @@ AddFileTypeSignaturePanel.signatureLabel.text=Signature AddFileTypeSignaturePanel.hexPrefixLabel.text=0x AddFileTypeSignaturePanel.offsetRelativeToLabel.text=Offset is relative to AddFileTypeSignaturePanel.offsetTextField.text= +FileTypeIdGlobalSettingsPanel.jLabel1.text=Signatures FileTypeIdGlobalSettingsPanel.editTypeButton.text=Edit Type AddFileTypePanel.mimeTypeTextField.text= AddFileTypePanel.mimeTypeLabel.text=MIME Type @@ -70,6 +72,4 @@ AddFileTypePanel.postHitCheckBox.text=Alert as an "Interesting File" when found AddFileTypePanel.setNameLabel.text=Set Name AddFileTypePanel.setNameTextField.text= FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text=Cannot make changes to file type definitions when ingest is running! -FileTypeIdGlobalSettingsPanel.descriptionLabel.text=Autopsy can automatically detect many file types. Add your custom file types here. -FileTypeIdGlobalSettingsPanel.customTypesLabel.text=Custom MIME Types: -FileTypeIdGlobalSettingsPanel.signaturesLabel.text=Signatures +FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here. diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 0f4db124af..44057d0016 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,10 +49,7 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Hash Set ingest module. \n\n\ - The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ - The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -181,10 +178,7 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ -The generated index will be left unusable. If you choose to continue,\n\ - please delete the corresponding -md5.idx file in the hash folder.\n\ - Exit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} @@ -211,6 +205,10 @@ AddContentToHashDbAction.singleSelectionNameEmpty=Add File to Hash Set (Empty Fi AddContentToHashDbAction.multipleSelectionNameEmpty=Add Files to Hash Set (Empty File) HashDbManager.ingestRunningExceptionMsg=Ingest is ongoing; this service will be unavailable until it finishes. HashDbManager.saveErrorExceptionMsg=Error saving hash configuration +HashLookupSettingsPanel.jButton3.text=Import Hash Set +HashLookupSettingsPanel.jLabel6.text=Type: +HashLookupSettingsPanel.jLabel4.text=Location: +HashLookupSettingsPanel.jLabel2.text=Name: HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=Calculate MD5 even if no hash set is selected HashLookupModuleSettingsPanel.knownHashDbsLabel.text=Select known hash sets to use: HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=Select notable hash sets to use: diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 3c275ee9cb..31a0690b82 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names @@ -109,14 +109,21 @@ FilesSetDefsPanel.ingest.deleteSetButton.text=Delete Filter FilesSetDefsPanel.interesting.jLabel6.text=Set Details FilesSetDefsPanel.ingest.jLabel6.text=Filter Details FilesSetDefsPanel.newRuleButton.text=New Rule +FilesSetDefsPanel.jLabel8.text=File Size: +FilesSetDefsPanel.jLabel7.text=MIME Type: FilesSetDefsPanel.rulePathConditionRegexCheckBox.text=Regex +FilesSetDefsPanel.jLabel4.text=Path Substring: +FilesSetDefsPanel.jLabel1.text=Rule Details FilesSetDefsPanel.dirsRadioButton.text=Directories +FilesSetDefsPanel.jLabel2.text=File Type: FilesSetDefsPanel.deleteRuleButton.text=Delete Rule FilesSetDefsPanel.fileNameRegexCheckbox.text=Substring / Regex FilesSetDefsPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files FilesSetDefsPanel.rulePathConditionTextField.text= FilesSetDefsPanel.fileNameRadioButton.text=Full Name +FilesSetDefsPanel.jLabel5.text=Description: FilesSetDefsPanel.fileNameTextField.text= +FilesSetDefsPanel.jLabel3.text=Name: FilesSetDefsPanel.fileNameExtensionRadioButton.text=Extension Only FilesSetDefsPanel.rulesListLabel.text=Rules: FilesSetDefsPanel.editRuleButton.text=Edit Rule @@ -133,10 +140,3 @@ FilesSetDefsPanel.modifiedDateLabel.text=Modified Within: FilesSetDefsPanel.daysIncludedTextField.text= FilesSetDefsPanel.daysIncludedLabel.text=day(s) FilesSetRulePanel.daysIncludedLabel.text=day(s) -FilesSetDefsPanel.nameLabel.text=Name: -FilesSetDefsPanel.descriptionLabel.text=Description: -FilesSetDefsPanel.fileTypeLabel.text=File Type: -FilesSetDefsPanel.ruleLabel.text=Rule Details -FilesSetDefsPanel.pathLabel.text=Path Substring: -FilesSetDefsPanel.mimeTypeLabel.text=MIME Type: -FilesSetDefsPanel.fileSizeLabel.text=File Size: diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 87dacfc16c..2dc971a40d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 32f6867f0c..0be7595111 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 92c55b614f..9aeeabc046 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -36,7 +36,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found KeywordSearchResultFactory.query.exception.msg=Could not perform the query OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. +OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Name=KeywordSearch OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index ebdce8a327..18deff87f4 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,6 +1,7 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: +Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -13,9 +14,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive -# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity +Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -24,6 +25,11 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file +ExtractIE.getBookmark.ere.noSpace=RecentActivity +ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. +ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. +ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. +Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -90,7 +96,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -192,7 +198,6 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. -# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index 199e018ea8..b20ccf5912 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Wed, 01 Apr 2020 15:51:37 -0400 +#Tue, 12 Nov 2019 17:21:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.14.0 +currentVersion=Autopsy 4.13.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 9368d6b951..998d3f715c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Wed, 01 Apr 2020 15:51:37 -0400 -CTL_MainWindow_Title=Autopsy 4.14.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 +#Tue, 12 Nov 2019 17:21:46 -0500 +CTL_MainWindow_Title=Autopsy 4.13.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 From ecb47c1a9caa3a415e825951a8a61210d4ae626f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 2 Apr 2020 15:33:43 -0400 Subject: [PATCH 14/49] update for disabled edge case --- .../optionspanel/Bundle.properties-MERGED | 12 ++++++------ .../optionspanel/EamDbSettingsDialog.java | 12 ++++++------ .../optionspanel/GlobalSettingsPanel.form | 8 +++++--- .../optionspanel/GlobalSettingsPanel.java | 15 +++++++++++---- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index b9d0716154..0fc6762cc3 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -12,14 +12,14 @@ EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository. EamDbSettingsDialog.lbDatabaseType.text=Database Type : EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time. EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database. -EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable). +EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Central Repository Database exists but is not the right format. Manually delete it or choose a different path (if applicable). EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database -EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it? +EamDbSettingsDialog.okButton.createDbDialog.message=Central Repository Database does not exist, would you like to create it? EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist -EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database -EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again. -EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again. -EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again. +EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Central Repository Database +EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Central Repository Database, please ensure address, port, and login credentials are correct for Postgres server and try again. +EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Central Repository Database, please ensure location exists and you have write permissions and try again. +EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to Central Repository Database. Please check your settings and try again. EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform. EamDbSettingsDialog.okButton.errorTitle.text=Restart Required. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 1e2c8126e0..54ede84070 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -159,14 +159,14 @@ public class EamDbSettingsDialog extends JDialog { * @return Whether or not the ultimate status after prompts is okay to continue. */ @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database", - "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", + "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Central Repository Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", "EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist", - "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", + "EamDbSettingsDialog.okButton.createDbDialog.message=Central Repository Database does not exist, would you like to create it?", "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again.", - "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", - "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", - "EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database"}) + "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to Central Repository Database. Please check your settings and try again.", + "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Central Repository Database, please ensure location exists and you have write permissions and try again.", + "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Central Repository Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", + "EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Central Repository Database"}) private static boolean promptTestStatusWarnings(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) { JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index c7fd365389..942a113ff8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -184,10 +184,12 @@
    - - - + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index baa24c787b..100f63cffb 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -251,8 +251,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.", }) private boolean testCurrentConfiguration() { + if (CentralRepoDbManager.getSavedDbChoice() == null || + CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.DISABLED || + !CentralRepoDbUtil.allowUseOfCentralRepository()) + return false; + CentralRepoDbManager manager = new CentralRepoDbManager(); DatabaseTestResult testResult = manager.testStatus(); + // if database doesn't exist, prompt user to create database if (testResult == DatabaseTestResult.DB_DOES_NOT_EXIST) { boolean success = EamDbSettingsDialog.promptCreateDatabase(manager, null); @@ -419,10 +425,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnDbConfigure) - .addComponent(bnTestConfigure) - .addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnDbConfigure) + .addComponent(bnTestConfigure))) .addGap(8, 8, 8)) ); From 83f4b5f4e5cff04c00dbccf76822de4e81a6b09e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 2 Apr 2020 15:47:22 -0400 Subject: [PATCH 15/49] remove unused imports --- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 100f63cffb..84a946db51 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -42,13 +42,11 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; -import java.awt.Dimension; import java.beans.PropertyChangeSupport; import java.util.logging.Level; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; -import org.sleuthkit.autopsy.centralrepository.optionspanel.Bundle; From c721a89f5fd928a5da89a4b2dfcc114d628208c0 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 2 Apr 2020 17:40:08 -0400 Subject: [PATCH 16/49] 6217 Refactor geo json attr utils --- .../autopsy/geolocation/datamodel/Route.java | 18 +-- .../autopsy/geolocation/datamodel/Track.java | 116 +++++++++--------- .../autopsy/modules/drones/DATExtractor.java | 16 +-- .../GPX_Module/GPX_Parser_Module.py | 18 ++- .../android/googlemaplocation.py | 10 +- InternalPythonModules/android/oruxmaps.py | 7 +- 6 files changed, 93 insertions(+), 92 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index 67de1e55ba..cbe54fe9c1 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -25,9 +25,9 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList.GeoWaypoint; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints; /** * A Route represents a TSK_GPS_ROUTE artifact which has a start and end point @@ -42,8 +42,6 @@ public class Route extends GeoPath { // This list is not expected to change after construction so the // constructor will take care of creating an unmodifiable List private final List propertiesList; - - private static final TskGeoWaypointsUtil attributeUtil = new TskGeoWaypointsUtil(); /** * Construct a route for the given artifact. @@ -119,9 +117,13 @@ public class Route extends GeoPath { } if (attribute != null) { - GeoWaypointList waypoints = attributeUtil.fromAttribute(attribute); - - for(GeoWaypoint waypoint: waypoints) { + GeoWaypoints waypoints; + try { + waypoints = BlackboardJsonAttrUtil.fromAttribute(attribute, GeoWaypoints.class); + } catch (InvalidJsonException ex) { + throw new GeoLocationDataException(String.format("Unable to parse waypoints in TSK_GEO_WAYPOINTS attribute (artifact object ID =%d)", artifact.getId()), ex); + } + for (GeoWaypoints.Waypoint waypoint : waypoints) { addToPath(new Waypoint(artifact, label, null, waypoint.getLatitude(), waypoint.getLongitude(), waypoint.getAltitude(), null, attributeMap, this)); } } else { diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index 213bd6b5f5..68da242b8a 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -1,5 +1,4 @@ /* - * * Autopsy Forensic Browser * * Copyright 2020 Basis Technology Corp. @@ -26,26 +25,24 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; /** * A GPS track with which wraps the TSK_GPS_TRACK artifact. */ -public final class Track extends GeoPath{ +public final class Track extends GeoPath { private final Long startTimestamp; private final Long endTimeStamp; - - private static final TskGeoTrackpointsUtil attributeUtil = new TskGeoTrackpointsUtil(); /** * Construct a new Track for the given artifact. - * + * * @param artifact - * - * @throws GeoLocationDataException + * + * @throws GeoLocationDataException */ public Track(BlackboardArtifact artifact) throws GeoLocationDataException { this(artifact, Waypoint.getAttributesFromArtifactAsMap(artifact)); @@ -53,49 +50,49 @@ public final class Track extends GeoPath{ /** * Construct a Track for the given artifact and attributeMap. - * - * @param artifact TSK_GPD_TRACK artifact - * @param attributeMap Map of the artifact attributes - * - * @throws GeoLocationDataException + * + * @param artifact TSK_GPD_TRACK artifact + * @param attributeMap Map of the artifact attributes + * + * @throws GeoLocationDataException */ private Track(BlackboardArtifact artifact, Map attributeMap) throws GeoLocationDataException { super(artifact, getTrackName(attributeMap)); - GeoTrackPointList points = getPointsList(attributeMap); + GeoTrackPoints points = getPointsList(attributeMap); buildPath(points, artifact); startTimestamp = points.getStartTime(); endTimeStamp = points.getEndTime(); } - + /** * Returns the start time of this track. - * - * @return Earliest time, or null if none was available. - * (seconds from java epoch) + * + * @return Earliest time, or null if none was available. (seconds from java + * epoch) */ public Long getStartTime() { return startTimestamp; } - + /** * Returns the end time of this track. - * - * @return Earliest timestamp, or null if none was available. - * (seconds from java epoch) + * + * @return Earliest timestamp, or null if none was available. (seconds from + * java epoch) */ public Long getEndTime() { return endTimeStamp; } /** - * Return the name of the track from the attributeMap. - * Track name is stored in the attribute TSK_NAME - * + * Return the name of the track from the attributeMap. Track name is stored + * in the attribute TSK_NAME + * * @param attributeMap - - * @return Track name or empty string if none was available. + * + * @return Track name or empty string if none was available. */ private static String getTrackName(Map attributeMap) { BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME); @@ -105,38 +102,41 @@ public final class Track extends GeoPath{ /** * Create the list of TrackWaypoints from the GeoTrackPoint list. - * - * @param points List of GeoTrackPoints - * + * + * @param points GeoTrackPoints object. * @param artifact The artifact to which these points belong - * - * @throws GeoLocationDataException + * + * @throws GeoLocationDataException */ @Messages({ "# {0} - track name", "GEOTrack_point_label_header=Trackpoint for track: {0}" }) - private void buildPath(GeoTrackPointList points, BlackboardArtifact artifact) - throws GeoLocationDataException { - for(GeoTrackPoint point: points) { + private void buildPath(GeoTrackPoints points, BlackboardArtifact artifact) throws GeoLocationDataException { + for (GeoTrackPoints.TrackPoint point : points) { addToPath(new TrackWaypoint(artifact, Bundle.GEOTrack_point_label_header(getLabel()), point)); } } /** - * Returns the list of GeoTrackPoints from the attributeMap. Creates the + * Returns the list of GeoTrackPoints from the attributeMap. Creates the * GeoTrackPoint list from the TSK_GEO_TRACKPOINTS attribute. - * + * * @param attributeMap Map of artifact attributes. - * + * * @return GeoTrackPoint list empty list if the attribute was not found. + * + * @throws GeoLocationDataException */ - private GeoTrackPointList getPointsList(Map attributeMap) { + private GeoTrackPoints getPointsList(Map attributeMap) throws GeoLocationDataException { BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); if (attribute != null) { - return attributeUtil.fromAttribute(attribute); + try { + return BlackboardJsonAttrUtil.fromAttribute(attribute, GeoTrackPoints.class); + } catch (InvalidJsonException ex) { + throw new GeoLocationDataException("Unable to parse track points in TSK_GEO_TRACKPOINTS attribute", ex); + } } - return null; } @@ -149,16 +149,16 @@ public final class Track extends GeoPath{ /** * Construct a TrackWaypoint. - * - * @param artifact the artifact to which this waypoint belongs - * + * + * @param artifact the artifact to which this waypoint belongs + * * @param pointLabel the label for the waypoint - * - * @param point GeoTrackPoint - * - * @throws GeoLocationDataException + * + * @param point GeoTrackPoint + * + * @throws GeoLocationDataException */ - TrackWaypoint(BlackboardArtifact artifact, String pointLabel, GeoTrackPoint point) throws GeoLocationDataException { + TrackWaypoint(BlackboardArtifact artifact, String pointLabel, GeoTrackPoints.TrackPoint point) throws GeoLocationDataException { super(artifact, pointLabel, point.getTimeStamp(), point.getLatitude(), @@ -172,10 +172,10 @@ public final class Track extends GeoPath{ } /** - * Overloaded to return a property list that is generated from - * the GeoTrackPoint instead of an artifact. - * - * @return unmodifiable list of Waypoint.Property + * Overloaded to return a property list that is generated from the + * GeoTrackPoint instead of an artifact. + * + * @return unmodifiable list of Waypoint.Property */ @Override public List getOtherProperties() { @@ -184,16 +184,16 @@ public final class Track extends GeoPath{ /** * Create a propertyList specific to GeoTrackPoints. - * + * * @param point GeoTrackPoint to get values from. - * + * * @return A list of Waypoint.properies. */ @Messages({ "Track_distanceTraveled_displayName=Distance traveled", "Track_distanceFromHome_displayName=Distance from home point" }) - private List createPropertyList(GeoTrackPoint point) { + private List createPropertyList(GeoTrackPoints.TrackPoint point) { List list = new ArrayList<>(); Long timestamp = point.getTimeStamp(); diff --git a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java index 97cfbd40be..3966317d15 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java @@ -41,11 +41,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint; import org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.Blackboard.BlackboardException; -import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.TrackPoint; /** * Extract drone position data from DJI Phantom drones. @@ -111,7 +111,7 @@ final class DATExtractor extends DroneExtractor { } // Process the csv file - GeoTrackPointList trackPoints = processCSVFile(context, DATFile, csvFilePath); + GeoTrackPoints trackPoints = processCSVFile(context, DATFile, csvFilePath); if (trackPoints != null && !trackPoints.isEmpty()) { (new GeoArtifactsHelper(getSleuthkitCase(), getName(), "DatCon", DATFile)).addTrack(DATFile.getName(), trackPoints, null); @@ -188,8 +188,8 @@ final class DATExtractor extends DroneExtractor { * * @throws DroneIngestException */ - private GeoTrackPointList processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException { - GeoTrackPointList trackPoints = new GeoTrackPointList(); + private GeoTrackPoints processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException { + GeoTrackPoints trackPoints = new GeoTrackPoints(); try (BufferedReader reader = new BufferedReader(new FileReader(new File(csvFilePath)))) { // First read in the header line and process String line = reader.readLine(); @@ -201,7 +201,7 @@ final class DATExtractor extends DroneExtractor { } String[] values = line.split(","); //NON-NLS - GeoTrackPoint point = createTrackPoint(headerMap, values); + TrackPoint point = createTrackPoint(headerMap, values); if (point != null) { trackPoints.addPoint(point); } @@ -246,7 +246,7 @@ final class DATExtractor extends DroneExtractor { * * @throws DroneIngestException */ - private GeoTrackPoint createTrackPoint(Map columnLookup, String[] values) throws DroneIngestException { + private TrackPoint createTrackPoint(Map columnLookup, String[] values) throws DroneIngestException { Double latitude = getDoubleValue(columnLookup.get(HEADER_LAT), values); Double longitude = getDoubleValue(columnLookup.get(HEADER_LONG), values); @@ -256,7 +256,7 @@ final class DATExtractor extends DroneExtractor { return null; } - return new GeoTrackPoint(latitude, + return new TrackPoint(latitude, longitude, getDoubleValue(columnLookup.get(HEADER_ALTITUDE), values), null, diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 6aeb84d5be..1c654503cb 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -37,12 +37,10 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoWaypointsUtil -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList import GeoWaypoint -from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil import GeoTrackPointList -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList import GeoTrackPoint +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints.Waypoint +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints.TrackPoint from org.sleuthkit.autopsy.datamodel import ContentUtils from org.sleuthkit.autopsy.ingest import IngestModule from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException @@ -166,7 +164,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): if self.writeDebugMsgs: self.log(Level.INFO, "Processing tracks from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") for track in gpx.tracks: for segment in track.segments: - geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList() + geoPointList = GeoTrackPoints() for point in segment.points: elevation = 0 @@ -180,7 +178,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): except Exception as e: self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) - geoPointList.addPoint(GeoTrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) + geoPointList.addPoint(TrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) try: geoArtifactHelper.addTrack("Track", geoPointList, None) @@ -213,10 +211,10 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): if self.writeDebugMsgs: self.log(Level.INFO, "Processing routes from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") for route in gpx.routes: - geoWaypointList = TskGeoWaypointsUtil.GeoWaypointList() + geoWaypoints = GeoWaypoints() for point in route.points: - geoWaypointList.addPoint(GeoWaypoint(point.latitude, point.longitude, point.elevation, point.name)) + geoWaypointList.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) try: geoArtifactHelper.addRoute(None, None, geoWaypointList, None) diff --git a/InternalPythonModules/android/googlemaplocation.py b/InternalPythonModules/android/googlemaplocation.py index 8e393dcee2..d2499cbf03 100644 --- a/InternalPythonModules/android/googlemaplocation.py +++ b/InternalPythonModules/android/googlemaplocation.py @@ -43,8 +43,8 @@ from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.Blackboard import BlackboardException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList -from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList import GeoWaypoint +from org.sleuthkit.datamodel.blackboardutils import GeoWaypoints +from org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints import Waypoint import traceback import general @@ -117,9 +117,9 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): source_lat = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lat")) source_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lng")) - waypointlist = GeoWaypointList() - waypointlist.addPoint(GeoWaypoint(source_lat, source_lng, None, None)) - waypointlist.addPoint(GeoWaypoint(dest_lat, dest_lng, None, dest_address)) + waypointlist = GeoWaypoints() + waypointlist.addPoint(Waypoint(source_lat, source_lng, None, None)) + waypointlist.addPoint(Waypoint(dest_lat, dest_lng, None, dest_address)) artifactHelper.addRoute(dest_title, time, waypointlist, None) diff --git a/InternalPythonModules/android/oruxmaps.py b/InternalPythonModules/android/oruxmaps.py index 7a939e1972..23920af069 100644 --- a/InternalPythonModules/android/oruxmaps.py +++ b/InternalPythonModules/android/oruxmaps.py @@ -45,7 +45,8 @@ from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.Blackboard import BlackboardException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints.TrackPoint import traceback import general @@ -139,14 +140,14 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): trackpointsQueryString = "SELECT trkptlat, trkptlon, trkptalt, trkpttime FROM trackpoints WHERE trkptseg = " + segmentId trackpointsResultSet = oruxMapsTrackpointsDb.runQuery(trackpointsQueryString) if trackpointsResultSet is not None: - geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList() + geoPointList = GeoTrackPoints() while trackpointsResultSet.next(): latitude = trackpointsResultSet.getDouble("trkptlat") longitude = trackpointsResultSet.getDouble("trkptlon") altitude = trackpointsResultSet.getDouble("trkptalt") time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch - geoPointList.addPoint(TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) + geoPointList.addPoint(TrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) try: geoartifact = geoArtifactHelper.addTrack(segmentName, geoPointList, None) From 528c0283a1b607036d8b2a060d18a71697c3974d Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 2 Apr 2020 20:20:56 -0400 Subject: [PATCH 17/49] 6217 Refactor geo json attr utils --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 4 ++-- InternalPythonModules/android/googlemaplocation.py | 2 +- InternalPythonModules/android/oruxmaps.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 1c654503cb..fe92d0d659 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -38,9 +38,9 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints.Waypoint +from org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints import Waypoint from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints.TrackPoint +from org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints import TrackPoint from org.sleuthkit.autopsy.datamodel import ContentUtils from org.sleuthkit.autopsy.ingest import IngestModule from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException diff --git a/InternalPythonModules/android/googlemaplocation.py b/InternalPythonModules/android/googlemaplocation.py index d2499cbf03..2c33146b21 100644 --- a/InternalPythonModules/android/googlemaplocation.py +++ b/InternalPythonModules/android/googlemaplocation.py @@ -43,7 +43,7 @@ from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.Blackboard import BlackboardException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils import GeoWaypoints +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints from org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints import Waypoint import traceback diff --git a/InternalPythonModules/android/oruxmaps.py b/InternalPythonModules/android/oruxmaps.py index 23920af069..283eab38b2 100644 --- a/InternalPythonModules/android/oruxmaps.py +++ b/InternalPythonModules/android/oruxmaps.py @@ -46,7 +46,7 @@ from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.Blackboard import BlackboardException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints.TrackPoint +from org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints import TrackPoint import traceback import general From 8c6fdf6bc21e16226407c72b95dfb2a0992201ac Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 2 Apr 2020 22:49:24 -0400 Subject: [PATCH 18/49] 6217 Refactor geo json attr utils --- Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index cbe54fe9c1..13a23b30e3 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -2,7 +2,7 @@ * * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 70b65b15dabf96b2e49bca2f02ecab2664e6680d Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 3 Apr 2020 09:45:02 -0400 Subject: [PATCH 19/49] 6219: TskCoreException thrown from normalizePhoneNum Do not attempt to create account when we do not have a valid phone number or email address. --- InternalPythonModules/android/calllog.py | 3 --- InternalPythonModules/android/general.py | 14 +++++--------- InternalPythonModules/android/textnow.py | 2 +- InternalPythonModules/android/whatsapp.py | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 5b3faf0697..13775e80f7 100644 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -103,10 +103,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): calleeId = None timeStamp = resultSet.getLong("date") / 1000 - number = resultSet.getString("number") - if not general.isValidPhoneNumer(number): - number = None duration = resultSet.getLong("duration") # duration of call is in seconds name = resultSet.getString("name") # name of person dialed or called. None if unregistered diff --git a/InternalPythonModules/android/general.py b/InternalPythonModules/android/general.py index daa789a57c..4048c05c0f 100644 --- a/InternalPythonModules/android/general.py +++ b/InternalPythonModules/android/general.py @@ -45,19 +45,15 @@ def appendAttachmentList(msgBody, attachmentsList): """ Checks if the given string might be a phone number. """ -def isValidPhoneNumer(data): - try: - return CommunicationsUtils.normalizePhoneNum(data) is not None - except TskCoreException as ex: - return False +def isValidPhoneNumber(data): + return CommunicationsUtils.isValidPhoneNumber(data) + """ Checks if the given string is a valid email address. """ def isValidEmailAddress(data): - try: - return CommunicationsUtils.normalizeEmailAddress(data) is not None - except TskCoreException as ex: - return False + return CommunicationsUtils.isValidEmailAddress(data) + diff --git a/InternalPythonModules/android/textnow.py b/InternalPythonModules/android/textnow.py index e05763cae9..005e1191dd 100644 --- a/InternalPythonModules/android/textnow.py +++ b/InternalPythonModules/android/textnow.py @@ -286,7 +286,7 @@ class TextNowContactsParser(TskContactsParser): def get_phone(self): number = self.result_set.getString("number") - return (number if general.isValidPhoneNumer(number) else None) + return (number if general.isValidPhoneNumber(number) else None) def get_email(self): # occasionally the 'number' column may have an email address instead diff --git a/InternalPythonModules/android/whatsapp.py b/InternalPythonModules/android/whatsapp.py index 5346545450..c67502d22b 100644 --- a/InternalPythonModules/android/whatsapp.py +++ b/InternalPythonModules/android/whatsapp.py @@ -435,7 +435,7 @@ class WhatsAppContactsParser(TskContactsParser): def get_phone(self): number = self.result_set.getString("number") - return (number if general.isValidPhoneNumer(number) else None) + return (number if general.isValidPhoneNumber(number) else None) def get_email(self): # occasionally the 'number' column may have an email address instead From 4303329f1f0f3428255961a92d36f1438d8afa17 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 3 Apr 2020 15:04:08 -0400 Subject: [PATCH 20/49] 6229: SEVERE errors from CR failing to handle custom account types --- .../datamodel/CorrelationAttributeUtil.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 14724fafb7..ea295c35d4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -215,7 +215,14 @@ public class CorrelationAttributeUtil { if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { // Get the corresponding CentralRepoAccountType from the database. - CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); + CentralRepoAccountType crAccountType; + try { + // @@TODO Vik-6136: CR currently does not know of custom account types. + // This try/catch prevents unnecessary exceptions, till CR handles implement custom account types + crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); + } catch (CentralRepoException ex) { + return; + } int corrTypeId = crAccountType.getCorrelationTypeId(); CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); From abedee28d95d3c6334d1243bed94a07c1ac5cf0d Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 06:33:30 -0400 Subject: [PATCH 21/49] 6190 cleaned up translated basic summary code --- .../autopsy/filequery/FileSearch.java | 107 +++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 5832625b73..0a9b14a8c0 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -23,6 +23,10 @@ import com.google.common.cache.CacheBuilder; import com.google.common.io.Files; import java.awt.Image; import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.nio.file.Paths; @@ -79,6 +83,9 @@ import org.sleuthkit.autopsy.textextractors.TextExtractor; import org.sleuthkit.autopsy.textextractors.TextExtractorFactory; import org.sleuthkit.autopsy.textsummarizer.TextSummarizer; import org.sleuthkit.autopsy.textsummarizer.TextSummary; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; /** * Main class to perform the file search. @@ -304,9 +311,105 @@ class FileSearch { } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex); } - image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM, + image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM, Image.SCALE_SMOOTH); - return new TextSummary(getFirstLines(file), image, countOfImages); + String summaryText = null; + if (file.getMD5Hash() != null) { + summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + } + if (StringUtils.isBlank(summaryText)) { + String firstLines = getFirstLines(file); + String translatedFirstLines = getTranslatedVersion(firstLines); + if (!StringUtils.isBlank(translatedFirstLines)) { + summaryText = translatedFirstLines; + if (file.getMD5Hash() != null) { + saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + } + } else { + summaryText = firstLines; + } + } + return new TextSummary(summaryText, image, countOfImages); + } + + /** + * Provide an English version of the specified String if it is not English, + * translation is enabled, and it can be translated. + * + * @param documentString The String to provide an English version of. + * + * @return The English version of the provided String, or null if no + * translation occurred. + */ + private static String getTranslatedVersion(String documentString) { + if (!LANGUAGE_DETECTOR.detect(documentString).isLanguage("en")) { + try { + TextTranslationService translatorInstance = TextTranslationService.getInstance(); + if (translatorInstance.hasProvider()) { + String translatedResult = translatorInstance.translate(documentString); + if (translatedResult.isEmpty() == false) { + return translatedResult; + } + } + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.INFO, "Error translating string for summary", ex); + } + } + return null; + } + + /** + * Find and load a saved summary from the case folder for the specified + * file. + * + * @param summarySavePath The full path for the saved summary file. + * + * @return The summary found given the specified path, null if no summary + * was found. + */ + private static String getSavedSummary(String summarySavePath) { + if (summarySavePath == null) { + return null; + } + File savedFile = new File(summarySavePath); + if (savedFile.exists()) { + try (BufferedReader bReader = new BufferedReader(new FileReader(savedFile))) { + // pass the path to the file as a parameter + StringBuilder sBuilder = new StringBuilder(); + String sCurrentLine = bReader.readLine(); + while (sCurrentLine != null) { + sBuilder.append(sCurrentLine).append("\n"); + sCurrentLine = bReader.readLine(); + } + return sBuilder.toString(); + } catch (IOException ingored) { + //summary file may not exist or may be incomplete in which case return null so a summary can be generated + } + } else { + try { //if the file didn't exist make sure the parent directories exist before we move on to creating a summary + Files.createParentDirs(savedFile); + } catch (IOException ex) { + logger.log(Level.WARNING, "Unable to create summaries directory in case folder for file at: " + summarySavePath, ex); + } + } + return null; //no saved summary was able to be found + } + + /** + * Save a summary at the specified location. + * + * @param summary The text of the summary being saved. + * @param summarySavePath The full path for the saved summary file. + */ + private static void saveSummary(String summary, String summarySavePath) { + if (summarySavePath == null) { + return; //can't save a summary if we don't have a path + } + try (FileWriter myWriter = new FileWriter(summarySavePath)) { + myWriter.write(summary); + } catch (IOException ex) { + logger.log(Level.WARNING, "Unable to save summary at: " + summarySavePath, ex); + } } /** From fb63359844c5393c32d2f55e0a2f4ffbfed29bd8 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 06:39:29 -0400 Subject: [PATCH 22/49] 6190 fix error handling --- .../autopsy/filequery/FileSearch.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 0a9b14a8c0..32dceb9e8e 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -314,16 +314,24 @@ class FileSearch { image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM, Image.SCALE_SMOOTH); String summaryText = null; - if (file.getMD5Hash() != null) { - summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + if (file.getMd5Hash() != null) { + try { + summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + } catch (NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to retrieve saved summary case not open", ex); + } } if (StringUtils.isBlank(summaryText)) { String firstLines = getFirstLines(file); String translatedFirstLines = getTranslatedVersion(firstLines); if (!StringUtils.isBlank(translatedFirstLines)) { summaryText = translatedFirstLines; - if (file.getMD5Hash() != null) { - saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + if (file.getMd5Hash() != null) { + try { + saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); + } catch (NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to save translated summary case not open", ex); + } } } else { summaryText = firstLines; @@ -342,18 +350,16 @@ class FileSearch { * translation occurred. */ private static String getTranslatedVersion(String documentString) { - if (!LANGUAGE_DETECTOR.detect(documentString).isLanguage("en")) { - try { - TextTranslationService translatorInstance = TextTranslationService.getInstance(); - if (translatorInstance.hasProvider()) { - String translatedResult = translatorInstance.translate(documentString); - if (translatedResult.isEmpty() == false) { - return translatedResult; - } + try { + TextTranslationService translatorInstance = TextTranslationService.getInstance(); + if (translatorInstance.hasProvider()) { + String translatedResult = translatorInstance.translate(documentString); + if (translatedResult.isEmpty() == false) { + return translatedResult; } - } catch (NoServiceProviderException | TranslationException ex) { - logger.log(Level.INFO, "Error translating string for summary", ex); } + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.INFO, "Error translating string for summary", ex); } return null; } From edbe64af90fff8a6cfa372be88941cb5efa4e71e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 07:14:21 -0400 Subject: [PATCH 23/49] 6235 sort types combo box to ensure Files is first --- .../commonpropertiessearch/InterCasePanel.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java index f36f8ab520..5eb521f3d5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonpropertiessearch; import org.sleuthkit.autopsy.guiutils.DataSourceComboBoxModel; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -119,6 +120,13 @@ public final class InterCasePanel extends javax.swing.JPanel { this.correlationTypeFilters = new HashMap<>(); try { List types = CentralRepository.getInstance().getDefinedCorrelationTypes(); + Collections.sort(types, new Comparator() { + //The types should be sorted so that the File type is the first item in the combo box. + @Override + public int compare(CorrelationAttributeInstance.Type type1, CorrelationAttributeInstance.Type type2) { + return Integer.compare(type1.getId(), type2.getId()); + } + }); for (CorrelationAttributeInstance.Type type : types) { correlationTypeFilters.put(type.getDisplayName(), type); this.correlationTypeComboBox.addItem(type.getDisplayName()); @@ -295,7 +303,7 @@ public final class InterCasePanel extends javax.swing.JPanel { private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed - boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files"); + boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files"); categoriesLabel.setEnabled(enableFileTypesFilter); allFileCategoriesRadioButton.setEnabled(enableFileTypesFilter); selectedFileCategoriesButton.setEnabled(enableFileTypesFilter); @@ -329,8 +337,8 @@ public final class InterCasePanel extends javax.swing.JPanel { // End of variables declaration//GEN-END:variables /** - * Get the map of cases which was used to populate the combo box on - * this panel. + * Get the map of cases which was used to populate the combo box on this + * panel. * * @return an unmodifiable copy of the map of cases */ @@ -339,8 +347,8 @@ public final class InterCasePanel extends javax.swing.JPanel { } /** - * Set the datamodel for the combo box which displays the cases in - * the central repository + * Set the datamodel for the combo box which displays the cases in the + * central repository * * @param dataSourceComboBoxModel the DataSourceComboBoxModel to use */ From 54d3cc53c3fabb341507f26ed61e7cdc1670d9a3 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 07:20:15 -0400 Subject: [PATCH 24/49] 6190 fix codacy complaint --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 32dceb9e8e..456a7210aa 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -384,7 +384,7 @@ class FileSearch { StringBuilder sBuilder = new StringBuilder(); String sCurrentLine = bReader.readLine(); while (sCurrentLine != null) { - sBuilder.append(sCurrentLine).append("\n"); + sBuilder.append(sCurrentLine).append('\n'); sCurrentLine = bReader.readLine(); } return sBuilder.toString(); From dd8f578ae35ad1e852ab3d8223c802692f725159 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 07:48:00 -0400 Subject: [PATCH 25/49] 6190 improve error message --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 456a7210aa..74a87c7a17 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -318,7 +318,7 @@ class FileSearch { try { summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); } catch (NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to retrieve saved summary case not open", ex); + logger.log(Level.WARNING, "Unable to retrieve saved summary. No case is open.", ex); } } if (StringUtils.isBlank(summaryText)) { @@ -330,7 +330,7 @@ class FileSearch { try { saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString()); } catch (NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to save translated summary case not open", ex); + logger.log(Level.WARNING, "Unable to save translated summary. No case is open.", ex); } } } else { From 27cd407d8676a90df77d9b85d5addc7459bc7159 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Mon, 6 Apr 2020 09:26:28 -0400 Subject: [PATCH 26/49] Search incoming account in the Account.PREDEFINED_ACCOUNT_TYPES list. --- .../datamodel/CorrelationAttributeUtil.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index ea295c35d4..e5b0d7ab50 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -211,18 +211,15 @@ public class CorrelationAttributeUtil { BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); + // @@TODO Vik-6136: CR currently does not know of custom account types. + // Ensure there is a predefined account type for this account. + Account.Type predefinedAccountType = Account.Type.PREDEFINED_ACCOUNT_TYPES.stream().filter(type -> type.getTypeName().equalsIgnoreCase(accountTypeStr)).findAny().orElse(null); + // do not create any correlation attribute instance for a Device account - if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { + if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false && predefinedAccountType != null) { // Get the corresponding CentralRepoAccountType from the database. - CentralRepoAccountType crAccountType; - try { - // @@TODO Vik-6136: CR currently does not know of custom account types. - // This try/catch prevents unnecessary exceptions, till CR handles implement custom account types - crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); - } catch (CentralRepoException ex) { - return; - } + CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); int corrTypeId = crAccountType.getCorrelationTypeId(); CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); From 76ef4fbd8e51248ccb9e7667c1a7f618b5026138 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 6 Apr 2020 09:31:43 -0400 Subject: [PATCH 27/49] 6190 make codacy happy --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 74a87c7a17..b25f83d195 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -390,6 +390,7 @@ class FileSearch { return sBuilder.toString(); } catch (IOException ingored) { //summary file may not exist or may be incomplete in which case return null so a summary can be generated + return null; //no saved summary was able to be found } } else { try { //if the file didn't exist make sure the parent directories exist before we move on to creating a summary @@ -397,8 +398,9 @@ class FileSearch { } catch (IOException ex) { logger.log(Level.WARNING, "Unable to create summaries directory in case folder for file at: " + summarySavePath, ex); } + return null; //no saved summary was able to be found } - return null; //no saved summary was able to be found + } /** From 922805c071812d4779a54983bac0161caacb9de0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 6 Apr 2020 14:57:11 -0400 Subject: [PATCH 28/49] Implemented and tested fixes for the regression --- .../DataContentViewerOtherCases.java | 2 +- .../datamodel/CorrelationAttributeUtil.java | 144 +++++++++++++----- .../eventlisteners/CaseEventListener.java | 4 +- .../eventlisteners/IngestEventsListener.java | 7 +- .../AnnotationsContentViewer.java | 2 +- .../autopsy/datamodel/GetSCOTask.java | 2 +- 6 files changed, 114 insertions(+), 47 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 881e60236e..1429a60312 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -464,7 +464,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // correlate on blackboard artifact attributes if they exist and supported BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node); if (bbArtifact != null && CentralRepository.isEnabled()) { - ret.addAll(CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact)); + ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact)); } // we can correlate based on the MD5 if it is enabled diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 14724fafb7..1b21505560 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.logging.Level; import org.openide.util.NbBundle.Messages; @@ -32,6 +33,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import org.sleuthkit.datamodel.CommunicationsUtils; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -59,28 +61,58 @@ public class CorrelationAttributeUtil { return Bundle.CorrelationAttributeUtil_emailaddresses_text(); } + // Defines which artifact types act as the sources for CR data. + // Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS + // TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the + // interesting artifact hit). + private static final HashSet SOURCE_TYPES_OF_CR_DATA = new HashSet() {{ + add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()); + add(ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()); + add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()); + add(ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()); + add(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()); + add(ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()); + add(ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()); + add(ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()); + add(ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()); + add(ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()); + add(ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()); + add(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()); + add(ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()); + }}; + /** * Makes zero to many correlation attribute instances from the attributes of - * an artifact. - * - * IMPORTANT: The correlation attribute instances are NOT added to the - * central repository by this method. - * - * @param artifact An artifact. + * artifacts that have correlatable data. The intention of this method is to + * use the results to save to the CR, not to correlate with them. If you + * want to correlate, please use makeCorrAttrsForCorrelation. An artifact that can + * have correlatable data != An artifact that should be the source of data + * in the CR, so results may be un-necessarily incomplete. + * + * @param artifact An artifact. * * @return A list, possibly empty, of correlation attribute instances for - * the artifact. + * the artifact. */ - public static List makeCorrAttrsFromArtifact(BlackboardArtifact artifact) { - return makeCorrAttrsFromArtifact(artifact, true ); + public static List makeCorrAttrsToSave(BlackboardArtifact artifact) { + if(SOURCE_TYPES_OF_CR_DATA.contains(artifact.getArtifactTypeID())) { + // Restrict the correlation attributes to use for saving. + // The artifacts which are suitable for saving are a subset of the + // artifacts that are suitable for correlating. + return makeCorrAttrsForCorrelation(artifact); + } + // Return an empty collection. + return new ArrayList<>(); } - + /** * Makes zero to many correlation attribute instances from the attributes of - * an artifact. + * artifacts that have correlatable data. The intention of this method is to + * use the results to correlate with, not to save. If you + * want to save, please use makeCorrAttrsToSave. An artifact that can + * have correlatable data != An artifact that should be the source of data + * in the CR, so results may be too lenient. * - * IMPORTANT: The correlation attribute instances are NOT added to the - * central repository by this method. * * TODO (Jira-6088): The methods in this low-level, utility class should * throw exceptions instead of logging them. The reason for this is that the @@ -91,26 +123,22 @@ public class CorrelationAttributeUtil { * checking is easy to forget, while catching exceptions is enforced. * * @param artifact An artifact. - * @param resolveSourceArtifact A flag to indicate whether to resolve the - * source artifact, if the given artifact is - * of type TSK_INTERESTING_ARTIFACT_HIT. * * @return A list, possibly empty, of correlation attribute instances for * the artifact. */ - public static List makeCorrAttrsFromArtifact(BlackboardArtifact artifact, boolean resolveSourceArtifact) { + public static List makeCorrAttrsForCorrelation(BlackboardArtifact artifact) { List correlationAttrs = new ArrayList<>(); - - // If the artifact is of type TSK_INTERESTING_ARTIFACT_HIT, and the caller - // has not indicated to resolve the source artifact, then return an empty list. - if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) && (resolveSourceArtifact == false) ) { - return correlationAttrs; - } try { BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); if (sourceArtifact != null) { int artifactTypeID = sourceArtifact.getArtifactTypeID(); - if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() + if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { + BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); + if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID); + } + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { @@ -143,6 +171,11 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { makeCorrAttrFromAcctArtifact(correlationAttrs, sourceArtifact); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { + makeCorrAttrFromArtifactPhoneAttr(correlationAttrs, sourceArtifact); } } } catch (CentralRepoException ex) { @@ -158,6 +191,51 @@ public class CorrelationAttributeUtil { return correlationAttrs; } + /** + * Makes a correlation attribute instance from a phone number attribute of an + * artifact. + * + * @param artifact An artifact with a phone number attribute. + * + * @return The correlation instance artifact or null, if the phone number is + * not a valid correlation attribute. + * + * @throws TskCoreException If there is an error querying the case + * database. + * @throws CentralRepoException If there is an error querying the central + * repository. + */ + private static void makeCorrAttrFromArtifactPhoneAttr(List corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { + CorrelationAttributeInstance corrAttr = null; + + /* + * Extract the phone number from the artifact attribute. + */ + String value = null; + if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); + } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); + } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); + } + + /* + * Normalize the phone number. + */ + if (value != null) { + try { + value = CommunicationsUtils.normalizePhoneNum(value); + corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); + if(corrAttr != null) { + corrAttrInstances.add(corrAttr); + } + } catch(TskCoreException ex) { + logger.log(Level.INFO, String.format("Phone number found in artifact %d did not pass validation.", artifact.getId())); + } + } + } + /** * Gets the associated artifact of a "meta-artifact" such as an interesting * artifact hit artifact. @@ -186,31 +264,23 @@ public class CorrelationAttributeUtil { /** * Makes a correlation attribute instance for an account artifact. - * + * * Also creates an account in the CR DB if it doesn't exist. * * IMPORTANT: The correlation attribute instance is NOT added to the central * repository by this method. * - * TODO (Jira-6088): The methods in this low-level, utility class should - * throw exceptions instead of logging them. The reason for this is that the - * clients of the utility class, not the utility class itself, should be in - * charge of error handling policy, per the Autopsy Coding Standard. Note - * that clients of several of these methods currently cannot determine - * whether receiving a null return value is an error or not, plus null - * checking is easy to forget, while catching exceptions is enforced. - * * @param corrAttrInstances A list of correlation attribute instances. * @param acctArtifact An account artifact. * * @return The correlation attribute instance. */ private static void makeCorrAttrFromAcctArtifact(List corrAttrInstances, BlackboardArtifact acctArtifact) throws TskCoreException, CentralRepoException { - + // Get the account type from the artifact BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); - + // do not create any correlation attribute instance for a Device account if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { @@ -441,10 +511,10 @@ public class CorrelationAttributeUtil { file.getId()); } catch (TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Error querying case database (%s)", file), ex); // NON-NLS + logger.log(Level.SEVERE, String.format("Error querying case database (%s)", file), ex); // NON-NLS return null; } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, String.format("Error querying central repository (%s)", file), ex); // NON-NLS + logger.log(Level.SEVERE, String.format("Error querying central repository (%s)", file), ex); // NON-NLS return null; } catch (CorrelationAttributeNormalizationException ex) { logger.log(Level.WARNING, String.format("Error creating correlation attribute instance (%s)", file), ex); // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 1df0e10dc6..8f648a9945 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -296,7 +296,7 @@ final class CaseEventListener implements PropertyChangeListener { return; } - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact); + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { eamArtifact.setComment(comment); try { @@ -369,7 +369,7 @@ final class CaseEventListener implements PropertyChangeListener { if (!hasTagWithConflictingKnownStatus) { //Get the correlation atttributes that correspond to the current BlackboardArtifactTag if their status should be changed //with the initial set of correlation attributes this should be a single correlation attribute - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbTag.getArtifact()); + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbTag.getArtifact()); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index b2bff50c98..bf347de026 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -455,11 +455,8 @@ public class IngestEventsListener { List eamArtifacts = new ArrayList<>(); for (BlackboardArtifact bbArtifact : bbArtifacts) { - // If the incoming artifact is of type TSK_INTERESTING_ARTIFACT_HIT, - // do not resolve to the source artifact, as correlation attributes - // for the source artifact would have already been created, - // when the event for that source artifact was received. - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact, false); + // makeCorrAttrToSave will filter out artifacts which should not be soruces of CR data. + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsToSave(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { try { // Only do something with this artifact if it's unique within the job diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 3c967db3fd..c5c92b11c0 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -198,7 +198,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data startSection(html, "Central Repository Comments"); List instancesList = new ArrayList<>(); if (artifact != null) { - instancesList.addAll(CorrelationAttributeUtil.makeCorrAttrsFromArtifact(artifact)); + instancesList.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(artifact)); } try { List artifactTypes = CentralRepository.getInstance().getDefinedCorrelationTypes(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java index 864f04f28a..5671ca6051 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java @@ -97,7 +97,7 @@ class GetSCOTask implements Runnable { logger.log(Level.WARNING, "Unable to get correlation type or value to determine value for O column for artifact", ex); } } else { - List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact); + List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); if (listOfPossibleAttributes.size() > 1) { //Don't display anything if there is more than 1 correlation property for an artifact but let the user know description = Bundle.GetSCOTask_occurrences_multipleProperties(); From bdcbb85f6002f6509fddb563d326cc02f44cb1c6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 6 Apr 2020 15:13:12 -0400 Subject: [PATCH 29/49] codacy --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 1b21505560..6fa9e0d133 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -65,7 +65,7 @@ public class CorrelationAttributeUtil { // Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS // TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the // interesting artifact hit). - private static final HashSet SOURCE_TYPES_OF_CR_DATA = new HashSet() {{ + private static final Set SOURCE_TYPES_OF_CR_DATA = new HashSet() {{ add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()); add(ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()); add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()); From 72f8aafbbab03ee1365a3e637cd8fca794132483 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 6 Apr 2020 15:14:35 -0400 Subject: [PATCH 30/49] codacy --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 6fa9e0d133..289b13b62a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.logging.Level; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; From 18359fc2e6fcf661d03a934e0de8bb3838c3f3a3 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 6 Apr 2020 15:15:37 -0400 Subject: [PATCH 31/49] Codacy and renamed variable --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 289b13b62a..15c796f858 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -66,7 +66,7 @@ public class CorrelationAttributeUtil { // Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS // TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the // interesting artifact hit). - private static final Set SOURCE_TYPES_OF_CR_DATA = new HashSet() {{ + private static final Set SOURCE_TYPES_FOR_CR_INSERT = new HashSet() {{ add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()); add(ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()); add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()); @@ -96,7 +96,7 @@ public class CorrelationAttributeUtil { * the artifact. */ public static List makeCorrAttrsToSave(BlackboardArtifact artifact) { - if(SOURCE_TYPES_OF_CR_DATA.contains(artifact.getArtifactTypeID())) { + if(SOURCE_TYPES_FOR_CR_INSERT.contains(artifact.getArtifactTypeID())) { // Restrict the correlation attributes to use for saving. // The artifacts which are suitable for saving are a subset of the // artifacts that are suitable for correlating. From 15d6ef1bc7061a089e3580fda0a6ec6336ee27c6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 7 Apr 2020 09:13:01 -0400 Subject: [PATCH 32/49] updates for not exiting EamDbSettingsDialog on error and not re-enabling Apply button --- .../optionspanel/EamDbSettingsDialog.java | 7 ++----- .../optionspanel/GlobalSettingsPanel.java | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 54ede84070..b9aadfdeee 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -530,8 +530,8 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - testStatusAndCreate(this, manager, this); - dispose(); + if (testStatusAndCreate(this, manager, this)) + dispose(); }//GEN-LAST:event_bnOkActionPerformed @@ -814,7 +814,6 @@ public class EamDbSettingsDialog extends JDialog { @Override public void changedUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); manager.clearStatus(); updateFullDbPath(); valid(); @@ -822,7 +821,6 @@ public class EamDbSettingsDialog extends JDialog { @Override public void insertUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); manager.clearStatus(); updateFullDbPath(); valid(); @@ -830,7 +828,6 @@ public class EamDbSettingsDialog extends JDialog { @Override public void removeUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); manager.clearStatus(); updateFullDbPath(); valid(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 84a946db51..f668e2f6d0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -88,6 +88,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } + /** + * Sets up this instance's listener for the GlobalSettingsPanel's changes. + */ private void setupSettingsChangeListeners() { // listen for change events in currently saved choice if (lastRegistered != null) { @@ -104,7 +107,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void onSettingsChange(PropertyChangeEvent evt) { ingestStateUpdated(Case.isCaseOpen()); clearStatus(); - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } @@ -644,7 +646,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i boolean changed = invokeCrChoice(this, null); if (changed) { load(); // reload db settings content and update buttons - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } }//GEN-LAST:event_bnDbConfigureActionPerformed @@ -663,7 +664,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i store(); load(); this.ingestStateUpdated(Case.isCaseOpen()); - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed private void bnTestConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConfigureActionPerformed From 618d2520a52d8a2432c81ccfd5989b1f8d80382b Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 7 Apr 2020 11:09:29 -0400 Subject: [PATCH 33/49] Fixed CVT unthreaded selection issue --- .../autopsy/communications/relationships/MessageViewer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java index 5e90d83c98..38e245aec3 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java @@ -247,6 +247,8 @@ public class MessageViewer extends JPanel implements RelationshipsViewer { */ private void showMessagesPane() { switchCard("messages"); + Outline outline = rootTablePane.getOutlineView().getOutline(); + outline.clearSelection(); } /** From 5937c8a8366a03aed83fc9c6f5656a4ba382b539 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 14:17:35 -0400 Subject: [PATCH 34/49] 6248: Fixed the geoloc zoom slider snap bug --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 4 +--- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index e915904d42..31527a830c 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -56,10 +56,10 @@ + - @@ -87,7 +87,6 @@ - @@ -116,7 +115,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 0462e77842..eefa0d5aae 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -310,7 +310,7 @@ final public class MapPanel extends javax.swing.JPanel { void setZoom(int zoom) { zoomChanging = true; mapViewer.setZoom(zoom); - zoomSlider.setValue((zoomSlider.getMaximum() + zoomSlider.getMinimum()) - zoom); + zoomSlider.setValue(zoom); zoomChanging = false; } @@ -572,8 +572,8 @@ final public class MapPanel extends javax.swing.JPanel { zoomSlider.setOrientation(javax.swing.JSlider.VERTICAL); zoomSlider.setPaintTicks(true); zoomSlider.setSnapToTicks(true); + zoomSlider.setInverted(true); zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100)); - zoomSlider.setOpaque(false); zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190)); zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { @@ -591,7 +591,6 @@ final public class MapPanel extends javax.swing.JPanel { zoomInBtn.setBorderPainted(false); zoomInBtn.setFocusPainted(false); zoomInBtn.setRequestFocusEnabled(false); - zoomInBtn.setRolloverEnabled(false); zoomInBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInBtnActionPerformed(evt); @@ -608,7 +607,6 @@ final public class MapPanel extends javax.swing.JPanel { zoomOutBtn.setBorderPainted(false); zoomOutBtn.setFocusPainted(false); zoomOutBtn.setRequestFocusEnabled(false); - zoomOutBtn.setRolloverEnabled(false); zoomOutBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutBtnActionPerformed(evt); From 9842156733379fa1d944d0b1094dc3ff70a60a6a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Tue, 7 Apr 2020 14:21:01 -0400 Subject: [PATCH 35/49] Addressed review feedback --- .../datamodel/CorrelationAttributeUtil.java | 74 ++++++++++--------- .../eventlisteners/IngestEventsListener.java | 2 +- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 15c796f858..f1d68b7db1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -66,6 +66,9 @@ public class CorrelationAttributeUtil { // Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS // TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the // interesting artifact hit). + + // IMPORTANT: This set should be updated for new artifacts types that need to + // be inserted into the CR. private static final Set SOURCE_TYPES_FOR_CR_INSERT = new HashSet() {{ add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()); add(ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()); @@ -114,6 +117,8 @@ public class CorrelationAttributeUtil { * have correlatable data != An artifact that should be the source of data * in the CR, so results may be too lenient. * + * IMPORTANT: The correlation attribute instances are NOT added to the + * central repository by this method. * * TODO (Jira-6088): The methods in this low-level, utility class should * throw exceptions instead of logging them. The reason for this is that the @@ -176,7 +181,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - makeCorrAttrFromArtifactPhoneAttr(correlationAttrs, sourceArtifact); + makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, sourceArtifact); } } } catch (CentralRepoException ex) { @@ -193,46 +198,49 @@ public class CorrelationAttributeUtil { } /** - * Makes a correlation attribute instance from a phone number attribute of an - * artifact. + * Makes correlation attribute instances from phone or email attributes + * found on communication-type artifacts. * - * @param artifact An artifact with a phone number attribute. - * - * @return The correlation instance artifact or null, if the phone number is - * not a valid correlation attribute. + * @param artifact A communication-type artifact * * @throws TskCoreException If there is an error querying the case * database. * @throws CentralRepoException If there is an error querying the central * repository. */ - private static void makeCorrAttrFromArtifactPhoneAttr(List corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { - CorrelationAttributeInstance corrAttr = null; - - /* - * Extract the phone number from the artifact attribute. - */ - String value = null; - if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); - } - - /* - * Normalize the phone number. - */ - if (value != null) { - try { - value = CommunicationsUtils.normalizePhoneNum(value); - corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); - if(corrAttr != null) { - corrAttrInstances.add(corrAttr); + private static void makeCorrAttrsFromCommunicationArtifacts(List corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { + for(BlackboardAttribute attribute : artifact.getAttributes()) { + BlackboardAttribute.Type attributeType = attribute.getAttributeType(); + if(attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_OFFICE)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_MOBILE))) { + String phoneNumber = attribute.getValueString(); + if(CommunicationsUtils.isValidPhoneNumber(phoneNumber)) { + String phoneNumberNorm = CommunicationsUtils.normalizePhoneNum(phoneNumber); + CorrelationAttributeInstance corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), phoneNumberNorm); + if(corrAttr != null) { + corrAttrInstances.add(corrAttr); + } + } + } else if (attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_HOME)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_OFFICE)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_REPLYTO)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC)) + || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC))) { + String emailAddress = attribute.getValueString(); + if(CommunicationsUtils.isValidEmailAddress(emailAddress)) { + String emailAddressNorm = CommunicationsUtils.normalizeEmailAddress(emailAddress); + CorrelationAttributeInstance corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.EMAIL_TYPE_ID), emailAddressNorm); + if(corrAttr != null) { + corrAttrInstances.add(corrAttr); + } } - } catch(TskCoreException ex) { - logger.log(Level.INFO, String.format("Phone number found in artifact %d did not pass validation.", artifact.getId())); } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index bf347de026..843e476499 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -455,7 +455,7 @@ public class IngestEventsListener { List eamArtifacts = new ArrayList<>(); for (BlackboardArtifact bbArtifact : bbArtifacts) { - // makeCorrAttrToSave will filter out artifacts which should not be soruces of CR data. + // makeCorrAttrToSave will filter out artifacts which should not be sources of CR data. List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsToSave(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { try { From 290a0fccea9f41a4d0900f24321ecc1ffec56f52 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 14:26:03 -0400 Subject: [PATCH 36/49] 6249: Swapped toolbar button positions --- Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java | 2 +- .../autopsy/report/infrastructure/ReportWizardAction.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java index 3d610890da..a64809a07d 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java @@ -50,7 +50,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction") @ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false) @ActionReferences(value = { - @ActionReference(path = "Toolbars/Case", position = 106)}) + @ActionReference(path = "Toolbars/Case", position = 107)}) public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar { private static final long serialVersionUID = 1L; diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java index 5b3d661665..236263200a 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java @@ -59,7 +59,7 @@ import org.sleuthkit.autopsy.report.ReportModule; @ActionReferences(value = { @ActionReference(path = "Menu/Tools", position = 301, separatorAfter = 399) , - @ActionReference(path = "Toolbars/Case", position = 107)}) + @ActionReference(path = "Toolbars/Case", position = 106)}) public final class ReportWizardAction extends CallableSystemAction implements Presenter.Toolbar, ActionListener { private static final Logger logger = Logger.getLogger(ReportWizardAction.class.getName()); From 87e3ba759c8a16e0b5c567c77a6013a7d481d4d8 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 7 Apr 2020 14:36:40 -0400 Subject: [PATCH 37/49] Setting MIME type before indexing test file --- .../configuration/MultiUserTestTool.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java index 8504bfd7c0..8148c23faa 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java @@ -57,6 +57,8 @@ import org.sleuthkit.autopsy.ingest.IngestJobStartResult; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleError; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; +import org.sleuthkit.autopsy.textextractors.TextExtractor; import org.sleuthkit.datamodel.AbstractFile; /** @@ -83,6 +85,7 @@ class MultiUserTestTool { "MultiUserTestTool.unableCreatFile=Unable to create a file in case output directory", "MultiUserTestTool.unableAddFileAsDataSource=Unable to add test file as data source to case", "MultiUserTestTool.unableToReadTestFileFromDatabase=Unable to read test file info from case database", + "MultiUserTestTool.unableToInitializeFilTypeDetector=Unable to initialize File Type Detector", "MultiUserTestTool.unableToUpdateKWSIndex=Unable to write to Keyword Search index", "MultiUserTestTool.unableToRunIngest=Unable to run ingest on test data source", "MultiUserTestTool.unexpectedError=Unexpected error while performing Multi User test", @@ -187,6 +190,16 @@ class MultiUserTestTool { } AbstractFile file = listOfFiles.get(0); + + // Set MIME type of the test file (required to test indexing) + FileTypeDetector fileTypeDetector = null; + try { + fileTypeDetector = new FileTypeDetector(); + } catch (FileTypeDetector.FileTypeDetectorInitException ex) { + return Bundle.MultiUserTestTool_unableToInitializeFilTypeDetector() + ". " + ex.getMessage(); + } + String mimeType = fileTypeDetector.getMIMEType(file); + file.setMIMEType(mimeType); // write to KWS index KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class); From e853e3aab9a699dfe3ffd1935ce9936f39caadfa Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 7 Apr 2020 14:48:45 -0400 Subject: [PATCH 38/49] Setting MIME type before indexing test file --- .../autopsy/experimental/configuration/MultiUserTestTool.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java index 8148c23faa..c622d452b5 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/MultiUserTestTool.java @@ -58,7 +58,6 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleError; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; -import org.sleuthkit.autopsy.textextractors.TextExtractor; import org.sleuthkit.datamodel.AbstractFile; /** From 0a5e98aa30f7bcfaf014ea97b6309931575b0bd3 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 15:38:57 -0400 Subject: [PATCH 39/49] 6248: Restoring ui settings --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 9 +++++++++ Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 3 +++ 2 files changed, 12 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index 31527a830c..1287c964c1 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -60,6 +60,9 @@ + + + @@ -87,6 +90,9 @@ + + + @@ -115,6 +121,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index eefa0d5aae..00ef520934 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -574,6 +574,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomSlider.setSnapToTicks(true); zoomSlider.setInverted(true); zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100)); + zoomSlider.setOpaque(false); zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190)); zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { @@ -591,6 +592,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomInBtn.setBorderPainted(false); zoomInBtn.setFocusPainted(false); zoomInBtn.setRequestFocusEnabled(false); + zoomInBtn.setRolloverEnabled(false); zoomInBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInBtnActionPerformed(evt); @@ -607,6 +609,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomOutBtn.setBorderPainted(false); zoomOutBtn.setFocusPainted(false); zoomOutBtn.setRequestFocusEnabled(false); + zoomOutBtn.setRolloverEnabled(false); zoomOutBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutBtnActionPerformed(evt); From b9660f974784881f3e15924e927eb88f09250135 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Tue, 7 Apr 2020 16:50:18 -0400 Subject: [PATCH 40/49] Reverted attribute util changes --- .../datamodel/CorrelationAttributeUtil.java | 63 +++++++++---------- 1 file changed, 29 insertions(+), 34 deletions(-) mode change 100644 => 100755 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java old mode 100644 new mode 100755 index f1d68b7db1..ee49b19c61 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -198,10 +198,13 @@ public class CorrelationAttributeUtil { } /** - * Makes correlation attribute instances from phone or email attributes - * found on communication-type artifacts. + * Makes a correlation attribute instance from a phone number attribute of an + * artifact. * - * @param artifact A communication-type artifact + * @param artifact An artifact with a phone number attribute. + * + * @return The correlation instance artifact or null, if the phone number is + * not a valid correlation attribute. * * @throws TskCoreException If there is an error querying the case * database. @@ -209,37 +212,29 @@ public class CorrelationAttributeUtil { * repository. */ private static void makeCorrAttrsFromCommunicationArtifacts(List corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { - for(BlackboardAttribute attribute : artifact.getAttributes()) { - BlackboardAttribute.Type attributeType = attribute.getAttributeType(); - if(attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_OFFICE)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_MOBILE))) { - String phoneNumber = attribute.getValueString(); - if(CommunicationsUtils.isValidPhoneNumber(phoneNumber)) { - String phoneNumberNorm = CommunicationsUtils.normalizePhoneNum(phoneNumber); - CorrelationAttributeInstance corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), phoneNumberNorm); - if(corrAttr != null) { - corrAttrInstances.add(corrAttr); - } - } - } else if (attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_HOME)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_OFFICE)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_REPLYTO)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC)) - || attributeType.equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC))) { - String emailAddress = attribute.getValueString(); - if(CommunicationsUtils.isValidEmailAddress(emailAddress)) { - String emailAddressNorm = CommunicationsUtils.normalizeEmailAddress(emailAddress); - CorrelationAttributeInstance corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.EMAIL_TYPE_ID), emailAddressNorm); - if(corrAttr != null) { - corrAttrInstances.add(corrAttr); - } + CorrelationAttributeInstance corrAttr = null; + + /* + * Extract the phone number from the artifact attribute. + */ + String value = null; + if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); + } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); + } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { + value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); + } + + /* + * Normalize the phone number. + */ + if (value != null) { + if(CommunicationsUtils.isValidPhoneNumber(value)) { + value = CommunicationsUtils.normalizePhoneNum(value); + corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); + if(corrAttr != null) { + corrAttrInstances.add(corrAttr); } } } From 36a70a5e0c1cbedf0e66d9fdbc0926c07e411eb2 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 07:45:43 -0400 Subject: [PATCH 41/49] Report doc fixes --- docs/doxygen/modReport.dox | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/doxygen/modReport.dox b/docs/doxygen/modReport.dox index 563a151c43..50c7215198 100644 --- a/docs/doxygen/modReport.dox +++ b/docs/doxygen/modReport.dox @@ -5,7 +5,7 @@ Report modules allow Autopsy users to create different report types. Autopsy co All custom report modules will be general report modules. General report modules have a single method to generate the report. This method gives the module freedom to find and process any data it so chooses. General modules also have the ability to provide a configuration panel, allowing the user to choose from various displayed settings. The report module may then use the user's selection to generate a more specific report. -General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It contains basic API to start, stop, and add to the progress bar, as well as update the processing label. The module is also expected to check the progress bar's status occasionally to see if the user has manually canceled the report. +General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It defines a basic API to start, stop, and increment the progress bar and to update the processing label. The module is also expected to check the progress bar's status occasionally to see if the user has manually canceled the report. \section report_create_module Creating a Report Module To create a report module, start off by creating a new Java or Python (Jython) class and implementing (Java) or inheriting (Jython) from org.sleuthkit.autopsy.report.GeneralReportModule. You'll need to override multiple methods including the following: @@ -17,11 +17,11 @@ To create a report module, start off by creating a new Java or Python (Jython) c If your report module requires configuration, you'll need to override: - org.sleuthkit.autopsy.report.GeneralReportModule.getConfigurationPanel() -For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to aquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses. +For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to acquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses. When updating the progress panel, it is recommended to update it as infrequently as possible, while still keeping the user informed. If your report processes 100,000 files and you chose to update the UI each time a file is reviewed, the UI would freeze when trying to process all your requests. This would cause problems to not only your reporting module, but to other modules running in parallel. A safer approach would be to update the UI every 1,000 files, or when a certain "category" of the files being processed has changed. For example, the HTML report module increments the progress bar and changes the processing label every time a new Blackboard Artifact Type is being processed. -Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard. This panel can be used to allow the user custom controls over the report. To make this panel, use NetBeans to make a new JPanel class and use its layout interface to put the UI widgets in the places that you want them. Then, your getConfigurationPanel() method should create an instance of that class and return it. +Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard. This panel can be used to allow the user to customize the report. To make this panel, use NetBeans to make a new JPanel class and use its layout interface to put the UI widgets in the places that you want them. Then, your getConfigurationPanel() method should create an instance of that class and return it. Typically a general report module should interact with both the Blackboard API in the org.sleuthkit.datamodel.SleuthkitCase class, in addition to an API (possibly external/thirdparty) to convert Blackboard Artifacts to the desired reporting format. @@ -32,7 +32,7 @@ You should call org.sleuthkit.autopsy.casemodule.Case.addReport() with the path \subsection report_create_module_indexing Indexing Reports -After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that it is indexed and can then be found by a user. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code: +After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that it is indexed and can then be found by a user running a keyword search. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code: \code{.java} KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class); From 7290c20d8551536bf82536d32a3aa26fbabb3d17 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Wed, 8 Apr 2020 10:39:53 -0400 Subject: [PATCH 42/49] 6248: Restoring form --- .../org/sleuthkit/autopsy/geolocation/MapPanel.form | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index 1287c964c1..e915904d42 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -56,13 +56,10 @@ - - - - + @@ -90,9 +87,7 @@ - - - + @@ -121,9 +116,7 @@ - - - + From 532f3063c7f72c45dda006a6d34ac27014eabc63 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 11:23:56 -0400 Subject: [PATCH 43/49] Update to openjdk in docs --- docs/doxygen-user/images/serviceinstall.PNG | Bin 20955 -> 31708 bytes docs/doxygen-user/images/wherejava.PNG | Bin 1017 -> 9711 bytes .../multi-user/installActiveMQ.dox | 4 ++-- docs/doxygen-user/multi-user/installSolr.dox | 10 +++++++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/doxygen-user/images/serviceinstall.PNG b/docs/doxygen-user/images/serviceinstall.PNG index 3a5ea81b47a43f409df7b3b3410e481d932c18c8..b20f07d9c8b25329b3e384956eb61af3af5dbf0b 100644 GIT binary patch literal 31708 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 QQe@G;VRF4#+cE6_05c+Pn*aa+ literal 20955 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 literal 1017 zcmeAS@N?(olHy`uVBq!ia0y~yUl}w0VAYX5{?}w0$<9pMbGwb~;L?@wFzD*JBq$(VIjJL<~k z+O^en_tLj6t38|HZydOOQSt8YKla%EzO^dvnNNM`wbj2u{eNev7SEi^dTZsojq}96 zny%h^GBW$y8p*}B_22AkmnB!OKjpgD`O5WM?{=Ot0T=;W$T_=G4+hzHgpq zo1NSGZ1c@`_g3Vail)}+ZZe8a-J`QUJ^ph|d~x7;7s=I;wpC$uap`3*?!2>|_PzLD zWvF@aw)zuBQSoP8w`x2t{p%h3v3|j-Szk@pzsk=4KIiJDxKfZyH_v)s6u5u($FNPa zD!)eh{<`XO^>bLU*YmRX8~@C-=DU05=DyCNsBWXk*zCZxrRCkpjdJ|I4qohz@O>?K zwzN1jz8V;8aaX=?T@ya{umAj)Yo6_n0eRcSPS%$Md7VmqPX!asM{SmE z%+>P|$DY5vdCpGy;?EazuFgB8f8qbsf1l#Moj&6I=ga>6wfB8Yn!EQLX0rXz|1ACS v`~K+_(}9WG|2WR%PDGBtP~u}__n%3p?OnHCoLCt!yE1sX`njxgN@xNAh6?w< diff --git a/docs/doxygen-user/multi-user/installActiveMQ.dox b/docs/doxygen-user/multi-user/installActiveMQ.dox index 4d7ab37fe5..475e558a08 100644 --- a/docs/doxygen-user/multi-user/installActiveMQ.dox +++ b/docs/doxygen-user/multi-user/installActiveMQ.dox @@ -8,14 +8,14 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w \section install_activemq_prereq Prerequisites You will need: -- 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html. +- 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. - Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0. \section install_activemq_install Installation \subsection install_activemq_install_java JRE Installation -Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output like the yellow results below, you have a JRE. +Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE.

    \image html wherejava.PNG

    diff --git a/docs/doxygen-user/multi-user/installSolr.dox b/docs/doxygen-user/multi-user/installSolr.dox index 3d55f29efc..f49c2e4b39 100644 --- a/docs/doxygen-user/multi-user/installSolr.dox +++ b/docs/doxygen-user/multi-user/installSolr.dox @@ -13,7 +13,7 @@ Solr's embedded ZooKeeper is also used as a coordination service for Autopsy. We use Bitnami Solr, which packages Solr as a Windows service. You will need: -- A 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html. +- A 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. - The Apache Solr 4.10.3-0 installation package. This is no longer available from its original source, but you can find it on our site: https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr. -- NOTE: We tested Solr 6 at one point, but ran into stability problems when loading and unloading cores. For now, you need to use Solr 4. - An installed version of Autopsy so that you can copy files from it. You can install Autopsy on one of the planned client systems. You do not need to install it on the Solr server. @@ -24,7 +24,11 @@ You will need: \section install_solr_install Installation \subsection install_solr_install_java JRE Installation -1. JREs are normally installed under "C:\Program Files\Java\jre(version)", so check there to see if you have one installed already. If not, get the installer as listed in the above Prerequisites section and install it with the default settings. +1. Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE. +

    +\image html wherejava.PNG +

    +If you need the JRE, install it with the default settings. \subsection install_solr_install_solr Solr Installation @@ -52,7 +56,7 @@ The following steps will configure Solr to run using an account that will have a + ++JvmOptions=-Dbootstrap_confdir="C:\Bitnami\solr-4.10.3-0\apache-solr\solr\configsets\AutopsyConfig\conf" + ++JvmOptions=-DzkRun
    - - Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: –-JavaHome="C:\Program Files\Java\jre1.8.0_111" + - Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: –-JavaHome="C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1"

    A portion of an updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.

    From 0f778596c0ac7532330fccc6c0218ceebc255c90 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 11:33:34 -0400 Subject: [PATCH 44/49] Review update --- docs/doxygen/modReport.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doxygen/modReport.dox b/docs/doxygen/modReport.dox index 50c7215198..90e40fb552 100644 --- a/docs/doxygen/modReport.dox +++ b/docs/doxygen/modReport.dox @@ -32,7 +32,7 @@ You should call org.sleuthkit.autopsy.casemodule.Case.addReport() with the path \subsection report_create_module_indexing Indexing Reports -After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that it is indexed and can then be found by a user running a keyword search. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code: +After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that the report text is indexed for keyword search. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code: \code{.java} KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class); From b7b6d95636bb17bbf8f2ac4b51a178f392613730 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 14:23:51 -0400 Subject: [PATCH 45/49] Updated release notes for 4.15 --- NEWS.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/NEWS.txt b/NEWS.txt index ee294d7fea..068408b413 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,32 @@ +---------------- VERSION 4.15.0 -------------- +New UI Features: +- Added Document view to File Discovery. +- Expanded Context Content Viewer to show if an app accessed a file. +- Added translation feature to Message Content Viewer. +- Added waypoint type filter to the Geolocation viewer. +- Added zoom feature to Indexed Text Content Viewer. + +New Ingest Modules Features: +- New GPX ingest module. +- New Drone ingest module for DJI drones based on DatCon. +- Create artifacts for files opened by Adobe Reader, Windows Media Player, Office Docs (Most Recently Used (MRU) and TrustRecords), 7Zip MRU, WinRAR MRU, Applets, Microsoft Management Console (MMC) via RegRipper. + +New Central Repository Features: +- Central Repository stores account IDs that were previously seen. +- Central Repository is enabled by default to store past hashes. Feature to flag previously seen files is disabled by default. + +Other New Features: +- Multi-user cases can be created via command line + +Bug fixes: +- Prevent entire application from crashing when gstreamer crashes on videos. +- Improve Geolocation viewer with large data sets. +- Fix error with non-sector aligned reads on local disks. +- Times from Recycle Bin files are now in timeline. +- Validate timeline events and ignore events too far in the future. +- Moved some database queries off of UI thread. +- Remove hard coded sizes from UI that cause issues with other languages. + ---------------- VERSION 4.14.0 -------------- Specialized UIs: - New File Discovery UI that allows you to search and filter for certain types of files. From 15d00d38c90aba157c09f569ccc625da6b5f894d Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 14:34:31 -0400 Subject: [PATCH 46/49] Fix doxygen warning --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 71c6b41f86..5cbc3307a0 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -201,11 +201,9 @@ public class CorrelationAttributeUtil { * Makes a correlation attribute instance from a phone number attribute of an * artifact. * + * @param corrAttrInstances Correlation attributes will be added to this. * @param artifact An artifact with a phone number attribute. * - * @return The correlation instance artifact or null, if the phone number is - * not a valid correlation attribute. - * * @throws TskCoreException If there is an error querying the case * database. * @throws CentralRepoException If there is an error querying the central From d5ed936797523f6521d6d143a5a12cbaa3729a7d Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Apr 2020 19:08:35 -0400 Subject: [PATCH 47/49] Release 4.15.0 version number changes --- Core/manifest.mf | 2 +- Core/nbproject/project.properties | 2 +- Core/nbproject/project.xml | 2 +- CoreLibs/manifest.mf | 4 ++-- Experimental/nbproject/project.xml | 4 ++-- ImageGallery/nbproject/project.xml | 4 ++-- KeywordSearch/nbproject/project.xml | 4 ++-- RecentActivity/nbproject/project.xml | 4 ++-- Testing/nbproject/project.xml | 2 +- docs/doxygen-user/Doxyfile | 4 ++-- docs/doxygen/Doxyfile | 4 ++-- nbproject/project.properties | 6 +++--- thunderbirdparser/nbproject/project.xml | 2 +- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Core/manifest.mf b/Core/manifest.mf index 494ba39afc..00681f3e7f 100644 --- a/Core/manifest.mf +++ b/Core/manifest.mf @@ -2,7 +2,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.core/10 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml -OpenIDE-Module-Implementation-Version: 30 +OpenIDE-Module-Implementation-Version: 31 OpenIDE-Module-Requires: org.openide.windows.WindowManager AutoUpdate-Show-In-Client: true AutoUpdate-Essential-Module: true diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index c7ceb01a4a..3fd1ed05d9 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -126,5 +126,5 @@ nbm.homepage=http://www.sleuthkit.org/ nbm.module.author=Brian Carrier nbm.needs.restart=true source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar -spec.version.base=10.18 +spec.version.base=10.19 diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 4aa97960f3..64d9509e59 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -251,7 +251,7 @@ 3 - 1.3 + 1.4 diff --git a/CoreLibs/manifest.mf b/CoreLibs/manifest.mf index 1f7fcc545e..95267126df 100644 --- a/CoreLibs/manifest.mf +++ b/CoreLibs/manifest.mf @@ -1,8 +1,8 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3 -OpenIDE-Module-Implementation-Version: 6 +OpenIDE-Module-Implementation-Version: 7 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties -OpenIDE-Module-Specification-Version: 1.3 +OpenIDE-Module-Specification-Version: 1.4 AutoUpdate-Show-In-Client: true AutoUpdate-Essential-Module: true diff --git a/Experimental/nbproject/project.xml b/Experimental/nbproject/project.xml index 90fbce3d76..166c73f0a5 100644 --- a/Experimental/nbproject/project.xml +++ b/Experimental/nbproject/project.xml @@ -135,7 +135,7 @@ 10 - 10.18 + 10.19 @@ -144,7 +144,7 @@ 3 - 1.3 + 1.4 diff --git a/ImageGallery/nbproject/project.xml b/ImageGallery/nbproject/project.xml index a7157df475..4ef4c1fde1 100644 --- a/ImageGallery/nbproject/project.xml +++ b/ImageGallery/nbproject/project.xml @@ -127,7 +127,7 @@ 10 - 10.18 + 10.19 @@ -136,7 +136,7 @@ 3 - 1.3 + 1.4 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 2de991d105..10e1e76bfe 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -119,7 +119,7 @@ 10 - 10.18 + 10.19 @@ -128,7 +128,7 @@ 3 - 1.3 + 1.4 diff --git a/RecentActivity/nbproject/project.xml b/RecentActivity/nbproject/project.xml index 89394f1b1f..f6465f00a5 100644 --- a/RecentActivity/nbproject/project.xml +++ b/RecentActivity/nbproject/project.xml @@ -60,7 +60,7 @@ 10 - 10.18 + 10.19 @@ -69,7 +69,7 @@ 3 - 1.3 + 1.4 diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml index def60a06ac..2ebb94a835 100644 --- a/Testing/nbproject/project.xml +++ b/Testing/nbproject/project.xml @@ -47,7 +47,7 @@ 10 - 10.18 + 10.19 diff --git a/docs/doxygen-user/Doxyfile b/docs/doxygen-user/Doxyfile index 6eb71ae8f8..0f985042a3 100644 --- a/docs/doxygen-user/Doxyfile +++ b/docs/doxygen-user/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy User Documentation" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.14.0 +PROJECT_NUMBER = 4.15.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -1025,7 +1025,7 @@ GENERATE_HTML = YES # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = 4.14.0 +HTML_OUTPUT = 4.15.0 # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 6490edacd6..993ee8ded2 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.14.0 +PROJECT_NUMBER = 4.15.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears a the top of each page and should give viewer a @@ -1066,7 +1066,7 @@ GENERATE_HTML = YES # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = api-docs/4.14.0/ +HTML_OUTPUT = api-docs/4.15.0/ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). diff --git a/nbproject/project.properties b/nbproject/project.properties index 1f61a9c967..7cb61fc13a 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -4,10 +4,10 @@ app.title=Autopsy ### lowercase version of above app.name=${branding.token} ### if left unset, version will default to today's date -app.version=4.14.0 +app.version=4.15.0 ### build.type must be one of: DEVELOPMENT, RELEASE -#build.type=RELEASE -build.type=DEVELOPMENT +build.type=RELEASE +#build.type=DEVELOPMENT project.org.netbeans.progress=org-netbeans-api-progress project.org.sleuthkit.autopsy.experimental=Experimental diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml index 4eebb3d2f4..29782066ac 100644 --- a/thunderbirdparser/nbproject/project.xml +++ b/thunderbirdparser/nbproject/project.xml @@ -36,7 +36,7 @@ 10 - 10.18 + 10.19 From 6ff3be941e3cd41229d94cd7ee36d8b1766181d6 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 9 Apr 2020 11:00:53 -0400 Subject: [PATCH 48/49] Specify Java 8 and add installer links. --- docs/doxygen-user/multi-user/installActiveMQ.dox | 2 +- docs/doxygen-user/multi-user/installSolr.dox | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doxygen-user/multi-user/installActiveMQ.dox b/docs/doxygen-user/multi-user/installActiveMQ.dox index 475e558a08..07a6f1dcfd 100644 --- a/docs/doxygen-user/multi-user/installActiveMQ.dox +++ b/docs/doxygen-user/multi-user/installActiveMQ.dox @@ -8,7 +8,7 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w \section install_activemq_prereq Prerequisites You will need: -- 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. +- 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild ( Link to installer) - Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0. diff --git a/docs/doxygen-user/multi-user/installSolr.dox b/docs/doxygen-user/multi-user/installSolr.dox index f49c2e4b39..1c3970e344 100644 --- a/docs/doxygen-user/multi-user/installSolr.dox +++ b/docs/doxygen-user/multi-user/installSolr.dox @@ -13,7 +13,7 @@ Solr's embedded ZooKeeper is also used as a coordination service for Autopsy. We use Bitnami Solr, which packages Solr as a Windows service. You will need: -- A 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. +- A 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. ( Link to installer) - The Apache Solr 4.10.3-0 installation package. This is no longer available from its original source, but you can find it on our site: https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr. -- NOTE: We tested Solr 6 at one point, but ran into stability problems when loading and unloading cores. For now, you need to use Solr 4. - An installed version of Autopsy so that you can copy files from it. You can install Autopsy on one of the planned client systems. You do not need to install it on the Solr server. From f43e375891685d47f292cbe05ff9f7d3a9a19124 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 10 Apr 2020 11:03:29 -0400 Subject: [PATCH 49/49] Change variable name --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index fe92d0d659..3d202a963b 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -214,10 +214,10 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): geoWaypoints = GeoWaypoints() for point in route.points: - geoWaypointList.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) + geoWaypoints.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) try: - geoArtifactHelper.addRoute(None, None, geoWaypointList, None) + geoArtifactHelper.addRoute(None, None, geoWaypoints, None) except Blackboard.BlackboardException as e: self.log("Error posting GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) except TskCoreException as e: