diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index 3b15568c2b..e4402a1b86 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -124,6 +124,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
+import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
import org.sleuthkit.autopsy.progress.LoggingProgressIndicator;
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
@@ -1477,16 +1478,7 @@ public class Case {
* @return The temp subdirectory path.
*/
public String getTempDirectory() {
- // get temp folder scoped to the combination of case name and timestamp
- // provided by getName()
- Path path = Paths.get(UserPreferences.getAppTempDirectory(), CASE_TEMP_DIR, getName());
- File f = path.toFile();
- // verify that the folder exists
- if (!f.exists()) {
- f.mkdirs();
- }
-
- return path.toAbsolutePath().toString();
+ return UserMachinePreferences.getTempDirectory();
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index 537c25c827..395b8cd830 100644
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -674,8 +674,7 @@ public final class UserPreferences {
* @return The absolute path to the application temp directory.
*/
public static String getAppTempDirectory() {
- return Paths.get(UserMachinePreferences.getBaseTempDirectory(), getAppName())
- .toAbsolutePath().toString();
+ return UserMachinePreferences.getTempDirectory();
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form
index 79746c704e..4c42c44668 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form
@@ -8,6 +8,8 @@
+
+
@@ -24,12 +26,12 @@
-
+
-
+
@@ -418,7 +420,7 @@
-
+
@@ -444,37 +446,53 @@
-
-
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
-
+
+
+
-
+
-
+
-
+
@@ -498,6 +516,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java
index 9a6af23efa..193b1836e9 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java
@@ -38,6 +38,7 @@ import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
+import org.apache.commons.lang3.StringUtils;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
@@ -47,9 +48,9 @@ import org.sleuthkit.autopsy.casemodule.GeneralFilter;
import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
import org.sleuthkit.autopsy.machinesettings.UserMachinePreferencesException;
import org.sleuthkit.autopsy.core.UserPreferences;
-import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.Version;
+import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences.TempDirChoice;
import org.sleuthkit.autopsy.report.ReportBranding;
/**
@@ -77,7 +78,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private final JFileChooser logoFileChooser;
private final JFileChooser tempDirChooser;
- private final TextFieldListener textFieldListener;
private static final String ETC_FOLDER_NAME = "etc";
private static final String CONFIG_FILE_EXTENSION = ".conf";
private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes
@@ -118,9 +118,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
solrMaxHeapSpinner.setModel(new javax.swing.SpinnerNumberModel(UserPreferences.getMaxSolrVMSize(),
JVM_MEMORY_STEP_SIZE_MB, ((int) getSystemMemoryInGB()) * MEGA_IN_GIGA, JVM_MEMORY_STEP_SIZE_MB));
- textFieldListener = new TextFieldListener();
+ TextFieldListener textFieldListener = new TextFieldListener();
agencyLogoPathField.getDocument().addDocumentListener(textFieldListener);
- tempDirectoryField.getDocument().addDocumentListener(textFieldListener);
+ tempCustomField.getDocument().addDocumentListener(new TempCustomTextListener());
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
reportBranding = new ReportBranding();
@@ -302,6 +302,16 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
return new String[]{};
}
+
+ private void evaluateTempDirState() {
+ boolean caseOpen = Case.isCaseOpen();
+ boolean customSelected = tempCustomRadio.isSelected();
+
+ tempDirectoryBrowseButton.setEnabled(!caseOpen && customSelected);
+ tempCustomField.setEnabled(!caseOpen && customSelected);
+
+ tempOnCustomNoPath.setVisible(customSelected && StringUtils.isBlank(tempCustomField.getText()));
+ }
/**
* Load the saved user preferences.
@@ -313,10 +323,25 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
specifyLogoRB.setSelected(!useDefault);
agencyLogoPathField.setEnabled(!useDefault);
browseLogosButton.setEnabled(!useDefault);
- tempDirectoryField.setText(UserMachinePreferences.getBaseTempDirectory());
+
+ tempCustomField.setText(UserMachinePreferences.getCustomTempDirectory());
+ switch (UserMachinePreferences.getTempDirChoice()) {
+ case CASE:
+ tempCaseRadio.setSelected(true);
+ break;
+ case CUSTOM:
+ tempCustomRadio.setSelected(true);
+ break;
+ default:
+ case SYSTEM:
+ tempLocalRadio.setSelected(true);
+ break;
+ }
+
+ evaluateTempDirState();
+
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
solrMaxHeapSpinner.setValue(UserPreferences.getMaxSolrVMSize());
- tempDirectoryField.setText(UserMachinePreferences.getBaseTempDirectory());
try {
updateAgencyLogo(path);
} catch (IOException ex) {
@@ -337,9 +362,13 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
private void setTempDirEnabled() {
boolean enabled = !Case.isCaseOpen();
- this.tempDirectoryBrowseButton.setEnabled(enabled);
- this.tempDirectoryField.setEnabled(enabled);
+
+ this.tempCaseRadio.setEnabled(enabled);
+ this.tempCustomRadio.setEnabled(enabled);
+ this.tempLocalRadio.setEnabled(enabled);
+
this.tempDirectoryWarningLabel.setVisible(!enabled);
+ evaluateTempDirState();
}
/**
@@ -371,12 +400,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
@Messages({
"AutopsyOptionsPanel_storeTempDir_onError_title=Error Saving Temporary Directory",
"# {0} - path",
- "AutopsyOptionsPanel_storeTempDir_onError_description=There was an error creating the temporary directory on the filesystem at: {0}.",})
+ "AutopsyOptionsPanel_storeTempDir_onError_description=There was an error creating the temporary directory on the filesystem at: {0}.",
+ "AutopsyOptionsPanel_storeTempDir_onChoiceError_title=Error Saving Temporary Directory Choice",
+ "AutopsyOptionsPanel_storeTempDir_onChoiceError_description=There was an error updating temporary directory choice selection.",})
private void storeTempDir() {
- String tempDirectoryPath = tempDirectoryField.getText();
- if (!UserMachinePreferences.getBaseTempDirectory().equals(tempDirectoryPath)) {
+ String tempDirectoryPath = tempCustomField.getText();
+ if (!UserMachinePreferences.getCustomTempDirectory().equals(tempDirectoryPath)) {
try {
- UserMachinePreferences.setBaseTempDirectory(tempDirectoryPath);
+ UserMachinePreferences.setCustomTempDirectory(tempDirectoryPath);
} catch (UserMachinePreferencesException ex) {
logger.log(Level.WARNING, "There was an error creating the temporary directory defined by the user: " + tempDirectoryPath, ex);
SwingUtilities.invokeLater(() -> {
@@ -387,6 +418,29 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
});
}
}
+
+ TempDirChoice choice;
+ if (tempCaseRadio.isSelected()) {
+ choice = TempDirChoice.CASE;
+ } else if (tempCustomRadio.isSelected()) {
+ choice = TempDirChoice.CUSTOM;
+ } else {
+ choice = TempDirChoice.SYSTEM;
+ }
+
+ if (!choice.equals(UserMachinePreferences.getTempDirChoice())) {
+ try {
+ UserMachinePreferences.setTempDirChoice(choice);
+ } catch (UserMachinePreferencesException ex) {
+ logger.log(Level.WARNING, "There was an error updating choice to: " + choice.name(), ex);
+ SwingUtilities.invokeLater(() -> {
+ JOptionPane.showMessageDialog(this,
+ String.format("%s", Bundle.AutopsyOptionsPanel_storeTempDir_onChoiceError_description()),
+ Bundle.AutopsyOptionsPanel_storeTempDir_onChoiceError_title(),
+ JOptionPane.ERROR_MESSAGE);
+ });
+ }
+ }
}
/**
@@ -554,6 +608,32 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}
+
+ /**
+ * Listens for changes in the temp directory custom directory text field.
+ */
+ private class TempCustomTextListener extends TextFieldListener {
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ evaluateTempDirState();
+ super.changedUpdate(e);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ evaluateTempDirState();
+ super.changedUpdate(e);
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ evaluateTempDirState();
+ super.changedUpdate(e);
+ }
+
+
+ }
/**
* This method is called from within the constructor to initialize the form.
@@ -567,6 +647,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
fileSelectionButtonGroup = new javax.swing.ButtonGroup();
displayTimesButtonGroup = new javax.swing.ButtonGroup();
logoSourceButtonGroup = new javax.swing.ButtonGroup();
+ tempDirChoiceGroup = new javax.swing.ButtonGroup();
jScrollPane1 = new javax.swing.JScrollPane();
javax.swing.JPanel mainPanel = new javax.swing.JPanel();
logoPanel = new javax.swing.JPanel();
@@ -593,9 +674,13 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
solrMaxHeapSpinner = new javax.swing.JSpinner();
solrJVMHeapWarning = new javax.swing.JLabel();
tempDirectoryPanel = new javax.swing.JPanel();
- tempDirectoryField = new javax.swing.JTextField();
+ tempCustomField = new javax.swing.JTextField();
tempDirectoryBrowseButton = new javax.swing.JButton();
tempDirectoryWarningLabel = new javax.swing.JLabel();
+ tempLocalRadio = new javax.swing.JRadioButton();
+ tempCaseRadio = new javax.swing.JRadioButton();
+ tempCustomRadio = new javax.swing.JRadioButton();
+ tempOnCustomNoPath = new javax.swing.JLabel();
rdpPanel = new javax.swing.JPanel();
javax.swing.JScrollPane sizingScrollPane = new javax.swing.JScrollPane();
javax.swing.JTextPane sizingTextPane = new javax.swing.JTextPane();
@@ -822,7 +907,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
tempDirectoryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.border.title"))); // NOI18N
tempDirectoryPanel.setName(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.name")); // NOI18N
- tempDirectoryField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryField.text")); // NOI18N
+ tempCustomField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempCustomField.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(tempDirectoryBrowseButton, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryBrowseButton.text")); // NOI18N
tempDirectoryBrowseButton.addActionListener(new java.awt.event.ActionListener() {
@@ -834,6 +919,33 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
tempDirectoryWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(tempDirectoryWarningLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryWarningLabel.text")); // NOI18N
+ tempDirChoiceGroup.add(tempLocalRadio);
+ org.openide.awt.Mnemonics.setLocalizedText(tempLocalRadio, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempLocalRadio.text")); // NOI18N
+ tempLocalRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tempLocalRadioActionPerformed(evt);
+ }
+ });
+
+ tempDirChoiceGroup.add(tempCaseRadio);
+ org.openide.awt.Mnemonics.setLocalizedText(tempCaseRadio, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempCaseRadio.text")); // NOI18N
+ tempCaseRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tempCaseRadioActionPerformed(evt);
+ }
+ });
+
+ tempDirChoiceGroup.add(tempCustomRadio);
+ org.openide.awt.Mnemonics.setLocalizedText(tempCustomRadio, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempCustomRadio.text")); // NOI18N
+ tempCustomRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tempCustomRadioActionPerformed(evt);
+ }
+ });
+
+ tempOnCustomNoPath.setForeground(java.awt.Color.RED);
+ org.openide.awt.Mnemonics.setLocalizedText(tempOnCustomNoPath, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempOnCustomNoPath.text")); // NOI18N
+
javax.swing.GroupLayout tempDirectoryPanelLayout = new javax.swing.GroupLayout(tempDirectoryPanel);
tempDirectoryPanel.setLayout(tempDirectoryPanelLayout);
tempDirectoryPanelLayout.setHorizontalGroup(
@@ -841,23 +953,37 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(tempLocalRadio)
+ .addComponent(tempCaseRadio)
.addComponent(tempDirectoryWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 615, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
- .addComponent(tempDirectoryField, javax.swing.GroupLayout.PREFERRED_SIZE, 367, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(tempCustomRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(tempDirectoryBrowseButton)))
- .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(tempOnCustomNoPath)
+ .addGroup(tempDirectoryPanelLayout.createSequentialGroup()
+ .addComponent(tempCustomField, javax.swing.GroupLayout.PREFERRED_SIZE, 459, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(tempDirectoryBrowseButton)))))
+ .addContainerGap(158, Short.MAX_VALUE))
);
tempDirectoryPanelLayout.setVerticalGroup(
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
.addContainerGap()
+ .addComponent(tempLocalRadio)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(tempCaseRadio)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(tempDirectoryField)
+ .addComponent(tempCustomRadio)
+ .addComponent(tempCustomField)
.addComponent(tempDirectoryBrowseButton))
- .addGap(18, 18, 18)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(tempOnCustomNoPath)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(tempDirectoryWarningLabel)
- .addContainerGap())
+ .addGap(14, 14, 14))
);
gridBagConstraints = new java.awt.GridBagConstraints();
@@ -910,11 +1036,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
);
}// //GEN-END:initComponents
@@ -931,7 +1057,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
if (!f.exists() && !f.mkdirs()) {
throw new InvalidPathException(specifiedPath, "Unable to create parent directories leading to " + specifiedPath);
}
- tempDirectoryField.setText(specifiedPath);
+ tempCustomField.setText(specifiedPath);
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
} catch (InvalidPathException ex) {
logger.log(Level.WARNING, "Unable to create temporary directory in " + specifiedPath, ex);
@@ -1021,6 +1147,21 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
}//GEN-LAST:event_browseLogosButtonActionPerformed
+ private void tempLocalRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tempLocalRadioActionPerformed
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ evaluateTempDirState();
+ }//GEN-LAST:event_tempLocalRadioActionPerformed
+
+ private void tempCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tempCaseRadioActionPerformed
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ evaluateTempDirState();
+ }//GEN-LAST:event_tempCaseRadioActionPerformed
+
+ private void tempCustomRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tempCustomRadioActionPerformed
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ evaluateTempDirState();
+ }//GEN-LAST:event_tempCustomRadioActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextField agencyLogoPathField;
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
@@ -1049,10 +1190,15 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
private javax.swing.JSpinner solrMaxHeapSpinner;
private javax.swing.JRadioButton specifyLogoRB;
private javax.swing.JLabel systemMemoryTotal;
+ private javax.swing.JRadioButton tempCaseRadio;
+ private javax.swing.JTextField tempCustomField;
+ private javax.swing.JRadioButton tempCustomRadio;
+ private javax.swing.ButtonGroup tempDirChoiceGroup;
private javax.swing.JButton tempDirectoryBrowseButton;
- private javax.swing.JTextField tempDirectoryField;
private javax.swing.JPanel tempDirectoryPanel;
private javax.swing.JLabel tempDirectoryWarningLabel;
+ private javax.swing.JRadioButton tempLocalRadio;
+ private javax.swing.JLabel tempOnCustomNoPath;
private javax.swing.JLabel totalMemoryLabel;
// End of variables declaration//GEN-END:variables
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index b880747533..bad8f8ff83 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -188,12 +188,11 @@ MultiUserSettingsPanel.restartRequiredLabel.text=Application restart required to
MultiUserSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect
MultiUserSettingsPanel.lbSolrNote1.text=Enter Solr 8 and/or Solr 4 server settings.
MultiUserSettingsPanel.lbSolrNote2.text=New text indexing can only be done with Solr 8.
-AutopsyOptionsPanel.tempDirectoryField.text=
AutopsyOptionsPanel.tempDirectoryBrowseButton.text=Browse
AutopsyOptionsPanel.a.AccessibleContext.accessibleName=Temp Directory
AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=Temp Directory
AutopsyOptionsPanel.tempDirectoryPanel.name=Temp Directory
-AutopsyOptionsPanel.tempDirectoryPanel.border.title=Temp Directory
+AutopsyOptionsPanel.tempDirectoryPanel.border.title=Root Temp Directory
AutopsyOptionsPanel.tempDirectoryWarningLabel.text=Close the current case to change the temporary directory.
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
@@ -247,3 +246,8 @@ AutopsyOptionsPanel.agencyLogoPathField.text=
AutopsyOptionsPanel.logoPanel.border.title=Logo
ViewPreferencesPanel.radioGroupByPersonHost.text=Group by Person/Host
ViewPreferencesPanel.radioGroupByDataType.text=Group by Data Type
+AutopsyOptionsPanel.tempLocalRadio.text=Local temp directory
+AutopsyOptionsPanel.tempCaseRadio.text=Temp folder in case directory
+AutopsyOptionsPanel.tempCustomRadio.text=Custom
+AutopsyOptionsPanel.tempCustomField.text=
+AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED
index a1520ece04..bcf95a19a9 100755
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED
@@ -12,6 +12,8 @@ AutopsyOptionsPanel.memFieldValidationLabel.noValueEntered.text=No value entered
AutopsyOptionsPanel.memFieldValidationLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB
# {0} - minimumMemory
AutopsyOptionsPanel.memFieldValidationLabel.underMinMemory.text=Value must be at least {0}GB
+AutopsyOptionsPanel_storeTempDir_onChoiceError_description=There was an error updating temporary directory choice selection.
+AutopsyOptionsPanel_storeTempDir_onChoiceError_title=Error Saving Temporary Directory Choice
# {0} - path
AutopsyOptionsPanel_storeTempDir_onError_description=There was an error creating the temporary directory on the filesystem at: {0}.
AutopsyOptionsPanel_storeTempDir_onError_title=Error Saving Temporary Directory
@@ -246,12 +248,11 @@ MultiUserSettingsPanel.restartRequiredLabel.text=Application restart required to
MultiUserSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect
MultiUserSettingsPanel.lbSolrNote1.text=Enter Solr 8 and/or Solr 4 server settings.
MultiUserSettingsPanel.lbSolrNote2.text=New text indexing can only be done with Solr 8.
-AutopsyOptionsPanel.tempDirectoryField.text=
AutopsyOptionsPanel.tempDirectoryBrowseButton.text=Browse
AutopsyOptionsPanel.a.AccessibleContext.accessibleName=Temp Directory
AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=Temp Directory
AutopsyOptionsPanel.tempDirectoryPanel.name=Temp Directory
-AutopsyOptionsPanel.tempDirectoryPanel.border.title=Temp Directory
+AutopsyOptionsPanel.tempDirectoryPanel.border.title=Root Temp Directory
AutopsyOptionsPanel.tempDirectoryWarningLabel.text=Close the current case to change the temporary directory.
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
@@ -305,3 +306,8 @@ AutopsyOptionsPanel.agencyLogoPathField.text=
AutopsyOptionsPanel.logoPanel.border.title=Logo
ViewPreferencesPanel.radioGroupByPersonHost.text=Group by Person/Host
ViewPreferencesPanel.radioGroupByDataType.text=Group by Data Type
+AutopsyOptionsPanel.tempLocalRadio.text=Local temp directory
+AutopsyOptionsPanel.tempCaseRadio.text=Temp folder in case directory
+AutopsyOptionsPanel.tempCustomRadio.text=Custom
+AutopsyOptionsPanel.tempCustomField.text=
+AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java
index 6c551da602..3bef43e0b2 100644
--- a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java
+++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java
@@ -95,9 +95,9 @@ final class DataSourceIngestPipeline extends IngestTaskPipeline {
ingestManager.setIngestTaskProgress(task, getDisplayName());
ingestJobPipeline.setCurrentFileIngestModule(getDisplayName(), file.getName());
ProcessResult result = module.process(file);
- if (result == ProcessResult.ERROR) {
- throw new IngestModuleException(String.format("%s experienced an error analyzing %s (file objId = %d)", getDisplayName(), file.getName(), file.getId())); //NON-NLS
- }
+// if (result == ProcessResult.ERROR) {
+// throw new IngestModuleException(String.format("%s experienced an error analyzing %s (file objId = %d)", getDisplayName(), file.getName(), file.getId())); //NON-NLS
+// }
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/machinesettings/UserMachinePreferences.java b/Core/src/org/sleuthkit/autopsy/machinesettings/UserMachinePreferences.java
index cc1538c9b7..ef7b138ef0 100644
--- a/Core/src/org/sleuthkit/autopsy/machinesettings/UserMachinePreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/machinesettings/UserMachinePreferences.java
@@ -20,10 +20,15 @@ package org.sleuthkit.autopsy.machinesettings;
import java.io.File;
import java.nio.file.Paths;
+import java.util.Optional;
import java.util.prefs.Preferences;
+import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
+import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.FileUtil;
/**
@@ -33,26 +38,122 @@ public final class UserMachinePreferences {
private static final Preferences preferences = NbPreferences.forModule(UserMachinePreferences.class);
- private static final String TEMP_DIR_KEY = "TempDirectory";
+ /**
+ * The user specified choice for where the temp directory should be located.
+ */
+ public enum TempDirChoice {
+ /**
+ * A custom location specified with an absolute path by the user.
+ */
+ CUSTOM,
+ /**
+ * Equivalent to java.io.tmpdir.
+ */
+ SYSTEM,
+ /**
+ * If a case is open, a sub directory of the case.
+ */
+ CASE;
+
+ /**
+ * Returns the temp directory choice that matches the string provided
+ * (whitespace and case insensitive).
+ *
+ * @param val The string value.
+ * @return The choice or empty if not found.
+ */
+ static Optional getValue(String val) {
+ if (val == null) {
+ return Optional.empty();
+ }
+
+ return Stream.of(TempDirChoice.values())
+ .filter(tempChoice -> tempChoice.name().equalsIgnoreCase(val.trim()))
+ .findFirst();
+ }
+ }
+
+ private static final String CUSTOM_TEMP_DIR_KEY = "TempDirectory";
+ private static final String TEMP_DIR_CHOICE_KEY = "TempDirChoice";
+
+ private static final String AUTOPSY_SUBDIR = UserPreferences.getAppName();
+ private static final String CASE_SUBDIR = "Temp";
+
+ private static final TempDirChoice DEFAULT_CHOICE = TempDirChoice.SYSTEM;
/**
- * Retrieves a default temporary directory that is a subdirectory of
- * java.io.tmpdir.
- *
- * @return The absolute path to the temp directory.
+ * @return A subdirectory of java.io.tmpdir.
*/
- private static String getDefaultTempDirectory() {
- return Paths.get(System.getProperty("java.io.tmpdir")).toAbsolutePath().toString();
+ private static File getSystemTempDirFile() {
+ return Paths.get(System.getProperty("java.io.tmpdir"), AUTOPSY_SUBDIR).toFile();
}
/**
- * Retrieves the base user-specified temporary directory.
+ * @return A subdirectory of the open case or getSystemTempDirFile if no
+ * open case.
+ */
+ private static File getCaseTempDirFile() {
+ try {
+ String caseDirStr = Case.getCurrentCaseThrows().getCaseDirectory();
+ return Paths.get(caseDirStr, CASE_SUBDIR).toFile();
+ } catch (NoCurrentCaseException ex) {
+ return getSystemTempDirFile();
+ }
+ }
+
+ /**
+ * Returns the custom directory subdirectory to be used for temp files
+ * (otherwise java.io.tmpdir subdir).
+ *
+ * @return A subdirectory of the custom user-specified path. If no path is
+ * specified, getSystemTempDirFile() is returned instead.
+ */
+ private static File getCustomTempDirFile() {
+ String customDirectory = getCustomTempDirectory();
+ return (StringUtils.isBlank(customDirectory))
+ ? getSystemTempDirFile() : Paths.get(customDirectory, AUTOPSY_SUBDIR).toFile();
+ }
+
+ /**
+ * Returns the temp directory file to use based on user choice.
+ *
+ * @return The directory.
+ */
+ private static File getTempDirFile() {
+ TempDirChoice choice = getTempDirChoice();
+ switch (choice) {
+ case CASE:
+ return getCaseTempDirFile();
+ case CUSTOM:
+ return getCustomTempDirFile();
+ case SYSTEM:
+ default:
+ return getSystemTempDirFile();
+ }
+ }
+
+ /**
+ * Returns the temp directory to use based on settings. This method also
+ * ensures the temp directory has been created.
*
* @return The base user-specified temporary directory.
*/
- public static String getBaseTempDirectory() {
- String tempDir = preferences.get(TEMP_DIR_KEY, null);
- return StringUtils.isBlank(tempDir) ? getDefaultTempDirectory() : tempDir;
+ public static String getTempDirectory() {
+ File dir = getTempDirFile();
+ dir = dir == null ? getSystemTempDirFile() : dir;
+
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ return dir.getAbsolutePath();
+ }
+
+ /**
+ * @return The user-specified custom temp directory path or empty string.
+ */
+ public static String getCustomTempDirectory() {
+ return preferences.get(CUSTOM_TEMP_DIR_KEY, "");
}
/**
@@ -64,8 +165,7 @@ public final class UserMachinePreferences {
* @return True if this is a valid location for a temp directory.
*
* @throws UserMachinePreferencesException If path could not be validated
- * due to mkdirs failure or the
- * directory is not read/write.
+ * due to mkdirs failure or the directory is not read/write.
*/
@NbBundle.Messages({
"# {0} - path",
@@ -96,11 +196,33 @@ public final class UserMachinePreferences {
* @param path The path to the directory.
*
* @throws UserMachinePreferencesException If the directory cannot be
- * accessed or created.
+ * accessed or created.
*/
- public static void setBaseTempDirectory(String path) throws UserMachinePreferencesException {
+ public static void setCustomTempDirectory(String path) throws UserMachinePreferencesException {
validateTempDirectory(path);
- preferences.put(TEMP_DIR_KEY, path);
+ preferences.put(CUSTOM_TEMP_DIR_KEY, path);
+ }
+
+ /**
+ * @return The user selection for how the temp directory should be handled
+ * (temp directory in case folder, in java.io.tmpdir, custom path).
+ */
+ public static TempDirChoice getTempDirChoice() {
+ return TempDirChoice.getValue(preferences.get(TEMP_DIR_CHOICE_KEY, null))
+ .orElse(DEFAULT_CHOICE);
+ }
+
+ /**
+ * Sets the temp directory choice (i.e. system, case, custom).
+ * @param tempDirChoice The choice (must be non-null).
+ * @throws UserMachinePreferencesException
+ */
+ public static void setTempDirChoice(TempDirChoice tempDirChoice) throws UserMachinePreferencesException {
+ if (tempDirChoice == null) {
+ throw new UserMachinePreferencesException("Expected non-null temp dir choice");
+ }
+
+ preferences.put(TEMP_DIR_CHOICE_KEY, tempDirChoice.name());
}
private UserMachinePreferences() {
diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml
index 7457154839..303f0a04bb 100644
--- a/CoreLibs/ivy.xml
+++ b/CoreLibs/ivy.xml
@@ -14,7 +14,7 @@
-
+
diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties
index 3d8ebb951a..60d2362fd8 100644
--- a/CoreLibs/nbproject/project.properties
+++ b/CoreLibs/nbproject/project.properties
@@ -42,8 +42,8 @@ file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.j
file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar
file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar
file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar
-file.reference.jna-5.7.0.jar=release/modules/ext/jna-5.7.0.jar
-file.reference.jna-platform-5.7.0.jar=release/modules/ext/jna-platform-5.7.0.jar
+file.reference.jna-5.8.0.jar=release/modules/ext/jna-5.8.0.jar
+file.reference.jna-platform-5.8.0.jar=release/modules/ext/jna-platform-5.8.0.jar
file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar
file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar
diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml
index 24219c333d..0d3dac9aa3 100644
--- a/CoreLibs/nbproject/project.xml
+++ b/CoreLibs/nbproject/project.xml
@@ -923,8 +923,8 @@
release/modules/ext/commons-compress-1.18.jar
- ext/jna-platform-5.7.0.jar
- release\modules\ext\jna-platform-5.7.0.jar
+ ext/jna-platform-5.8.0.jar
+ release\modules\ext\jna-platform-5.8.0.jar
ext/opencv-248.jar
@@ -951,8 +951,8 @@
release/modules/ext/imageio-bmp-3.2.jar
- ext/jna-5.7.0.jar
- release\modules\ext\jna-5.7.0.jar
+ ext/jna-5.8.0.jar
+ release\modules\ext\jna-5.8.0.jar
ext/commons-lang-2.6.jar
diff --git a/NEWS.txt b/NEWS.txt
index d437c75034..532aae69fa 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -33,6 +33,7 @@ Reporting:
Misc:
- Added support for Ext4 inline data and sparse blocks (via TSK fix).
+- Fixed timeline controller deadlock issue
- Updated PostgreSQL JDBC driver to support any recent version of PostgreSQL for multi-user cases and PostgreSQL Central Repository.
- Added personas to the summary viewer in CVT.
- Handling of bad characters in auto ingest manifest files.
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
index 8d215ccf6e..cdffe5e21a 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
@@ -876,9 +876,12 @@ class ExtractRegistry extends Extract {
try{
createOrUpdateOsAccount(regFile, sid, username, homeDir);
- } catch(TskCoreException | TskDataException ex) {
- logger.log(Level.SEVERE, String.format("Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid));
+ } catch (OsAccountManager.NotUserSIDException ex) {
+ logger.log(Level.WARNING, String.format("Cannot create OsAccount for file: %s, sid: %s is not a user SID.", regFile.getId(), sid));
}
+ catch(TskCoreException | TskDataException ex ) {
+ logger.log(Level.SEVERE, String.format("Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid));
+ }
BlackboardArtifact bbart = null;
try {
@@ -1216,7 +1219,10 @@ class ExtractRegistry extends Extract {
logger.log(Level.WARNING, "Error parsing the the date from the registry file", ex); //NON-NLS
} catch (TskDataException | TskCoreException ex) {
logger.log(Level.WARNING, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS
- } finally {
+ } catch (OsAccountManager.NotUserSIDException ex) {
+ logger.log(Level.WARNING, "Error creating OS Account, input SID is not a user SID.", ex); //NON-NLS
+ }
+ finally {
if (!context.dataSourceIngestIsCancelled()) {
postArtifacts(newArtifacts);
}
@@ -2206,8 +2212,9 @@ class ExtractRegistry extends Extract {
*
* @throws TskCoreException
* @throws TskDataException
+ * @throws OsAccountManager.NotUserSIDException
*/
- private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir) throws TskCoreException, TskDataException {
+ private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir) throws TskCoreException, TskDataException, OsAccountManager.NotUserSIDException {
OsAccountManager accountMgr = tskCase.getOsAccountManager();
HostManager hostMrg = tskCase.getHostManager();
Host host = hostMrg.getHost((DataSource)dataSource);
diff --git a/nbproject/platform.properties b/nbproject/platform.properties
index 7a61a6e1b6..32e681b3af 100644
--- a/nbproject/platform.properties
+++ b/nbproject/platform.properties
@@ -7,9 +7,9 @@ suite.dir=${basedir}
nbplatform.active=download
nbplatform.active.dir=${suite.dir}/netbeans-plat/${netbeans-plat-version}
harness.dir=${nbplatform.active.dir}/harness
-bootstrap.url=https://netbeans-vm.apache.org/uc/${netbeans-plat-version}/tasks.jar
+bootstrap.url=https://netbeans-vm1.apache.org/uc/${netbeans-plat-version}/tasks.jar
# Where we get the platform from. To see what versions are available, open URL in browser up to the .../updates part of the URL
-autoupdate.catalog.url=https://netbeans-vm.apache.org/uc/${netbeans-plat-version}/updates.xml.gz
+autoupdate.catalog.url=https://netbeans-vm1.apache.org/uc/${netbeans-plat-version}/updates.xml.gz
cluster.path=\
${nbplatform.active.dir}/harness:\
${nbplatform.active.dir}/java:\