From 9b89e88f2e75d57315c639eb6b05c1dac48e162d Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 22 Jul 2020 11:16:38 -0400 Subject: [PATCH 01/22] Updated MBoxParser to properly handle other mime types --- .../autopsy/thunderbirdparser/MimeJ4MessageParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java index 229615b7b3..7856da1a7b 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java @@ -231,11 +231,11 @@ class MimeJ4MessageParser { || e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN)) { handleTextBody(email, (TextBody) e.getBody(), e.getMimeType(), e.getHeader().getFields()); } else { - // Ignore other types. - } + handleAttachment(email, e, fileID, index); + } } } - + /** * Extract text out of a body part of the message. * From 66d1713ec5f6dcf2008531372a95d188769cb126 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 23 Jul 2020 10:45:27 -0400 Subject: [PATCH 02/22] Fixed multipart handling to support multiple text or html parts --- .../autopsy/thunderbirdparser/MimeJ4MessageParser.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java index 7856da1a7b..6a95e8729a 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/MimeJ4MessageParser.java @@ -21,13 +21,11 @@ package org.sleuthkit.autopsy.thunderbirdparser; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.logging.Level; -import org.apache.james.mime4j.dom.BinaryBody; import org.apache.james.mime4j.dom.Body; import org.apache.james.mime4j.dom.Entity; import org.apache.james.mime4j.dom.Message; @@ -227,8 +225,8 @@ class MimeJ4MessageParser { } else if (e.getDispositionType() != null && e.getDispositionType().equals(ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT)) { handleAttachment(email, e, fileID, index); - } else if (e.getMimeType().equals(HTML_TYPE) - || e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN)) { + } else if ((e.getMimeType().equals(HTML_TYPE) && (email.getHtmlBody() == null || email.getHtmlBody().isEmpty())) + || (e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN) && (email.getTextBody() == null || email.getTextBody().isEmpty()))) { handleTextBody(email, (TextBody) e.getBody(), e.getMimeType(), e.getHeader().getFields()); } else { handleAttachment(email, e, fileID, index); From a0898fddbea1b2b389869a3a4c9ba0beaa28cab5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 30 Jul 2020 16:00:35 -0400 Subject: [PATCH 03/22] beginnings of photorec extension exclusions --- .../modules/photoreccarver/Bundle.properties | 5 + .../PhotoRecCarverFileIngestModule.java | 52 ++++++- .../PhotoRecCarverIngestJobSettings.java | 113 ++++++++++++-- .../PhotoRecCarverIngestJobSettingsPanel.form | 142 +++++++++++++++++- .../PhotoRecCarverIngestJobSettingsPanel.java | 134 +++++++++++++++-- 5 files changed, 409 insertions(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties index 278caa666b..629113188e 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties @@ -19,3 +19,8 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files +PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Include or Exclude File Extensions +PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude +PhotoRecCarverIngestJobSettingsPanel.includeExcludeExtensionsLabel.text=Extensions to exclude / include (a comma-separated list) +PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text= +PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java index 4b2f8eddfa..3f89d84801 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java @@ -29,6 +29,7 @@ import java.nio.file.Paths; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -79,6 +80,9 @@ import org.sleuthkit.datamodel.TskData; final class PhotoRecCarverFileIngestModule implements FileIngestModule { static final boolean DEFAULT_CONFIG_KEEP_CORRUPTED_FILES = false; + static final boolean DEFAULT_CONFIG_FILE_OPT_OPTIONS = false; + static final boolean DEFAULT_CONFIG_INCLUDE_ELSE_EXCLUDE = false; + private static final String PHOTOREC_DIRECTORY = "photorec_exec"; //NON-NLS private static final String PHOTOREC_SUBDIRECTORY = "bin"; //NON-NLS @@ -99,9 +103,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { private File executableFile; private IngestServices services; private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities(); + private final PhotoRecCarverIngestJobSettings settings; private long jobId; - private final boolean keepCorruptedFiles; private static class IngestJobTotals { private final AtomicLong totalItemsRecovered = new AtomicLong(0); @@ -115,7 +119,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { * @param settings Ingest job settings used to configure the module. */ PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) { - keepCorruptedFiles = settings.isKeepCorruptedFiles(); + this.settings = settings; } private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) { @@ -177,6 +181,42 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { } } } + + + + private String getPhotorecOptions() { + List toRet = new ArrayList(); + + if (settings.hasFileOptOption()) { + String enable = "enable"; + String disable = "disable"; + + // if we are including file extensions, then we are excluding + // everything else and vice-versa. + String everythingEnable = settings.isIncludeElseExclude() ? + disable : enable; + + toRet.addAll(Arrays.asList("everything", everythingEnable)); + + final String itemEnable = settings.isIncludeElseExclude() ? + enable : disable; + + settings.getIncludeExcludeExtensions().forEach((extension) -> { + toRet.addAll(Arrays.asList(extension, itemEnable)); + }); + } + + if (settings.isKeepCorruptedFiles()) { + toRet.add("keep_corrupted_file"); + } + + if (toRet.size() > 0) { + toRet.add(0, "options"); + } + + toRet.add("search"); + return String.join(",", toRet); + } /** * @inheritDoc @@ -242,11 +282,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE, "/cmd", // NON-NLS tempFilePath.toFile().toString()); - if (keepCorruptedFiles) { - processAndSettings.command().add("options,keep_corrupted_file,search"); // NON-NLS - } else { - processAndSettings.command().add("search"); // NON-NLS - } + + String photorecOptions = getPhotorecOptions(); + processAndSettings.command().add(photorecOptions); // Add environment variable to force PhotoRec to run with the same permissions Autopsy uses processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java index 93de74f1d6..d87984fc94 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java @@ -18,7 +18,10 @@ */ package org.sleuthkit.autopsy.modules.photoreccarver; +import java.util.ArrayList; +import java.util.Collections; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import java.util.List; /** * Ingest job settings for the PhotoRec Carver module. @@ -26,45 +29,133 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSettings { private static final long serialVersionUID = 1L; - + private boolean keepCorruptedFiles; - + private List includeExcludeExtensions; + private boolean fileOptOption; + private boolean includeElseExclude; + /** * Instantiate the ingest job settings with default values. */ PhotoRecCarverIngestJobSettings() { - this.keepCorruptedFiles = PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES; + this(PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES, + PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_FILE_OPT_OPTIONS, + PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_INCLUDE_ELSE_EXCLUDE, + null); } - + /** - * Instantiate the ingest job settings. + * Sets the photo rec settings. * - * @param keepCorruptedFiles Keep corrupted files. + * @param keepCorruptedFiles Whether or not to keep corrupted files. + * @param fileOptOption Whether or not the file opt options + * should be enabled (whether or not to + * include/exclude file extensions). + * @param includeElseExclude If file opt options is enabled, whether + * to include only the extensions listed or + * exclude extensions from output. + * @param includeExcludeExtensions The extensions to include or exclude + * (i.e. jpg, gif) */ - PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles) { + public PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles, boolean fileOptOption, boolean includeElseExclude, List includeExcludeExtensions) { this.keepCorruptedFiles = keepCorruptedFiles; + this.fileOptOption = fileOptOption; + this.includeElseExclude = includeElseExclude; + setIncludeExcludeExtensions(includeExcludeExtensions); } @Override public long getVersionNumber() { return serialVersionUID; } - + /** * Are corrupted files being kept? - * + * * @return True if keeping corrupted files; otherwise false. */ boolean isKeepCorruptedFiles() { return keepCorruptedFiles; } - + /** * Keep or disgard corrupted files. - * + * * @param keepCorruptedFiles Are corrupted files being kept? */ void setKeepCorruptedFiles(boolean keepCorruptedFiles) { this.keepCorruptedFiles = keepCorruptedFiles; } + + /** + * Gets extension names (i.e. jpg, exe) to include or exclude from photorec + * carving. + * + * @return The extension names. + */ + public List getIncludeExcludeExtensions() { + return Collections.unmodifiableList(includeExcludeExtensions); + } + + /** + * Sets extension names (i.e. jpg, exe) to include or exclude from photorec + * carving. + * + * @param includeExcludeExtensions The extension names. + */ + public void setIncludeExcludeExtensions(List includeExcludeExtensions) { + this.includeExcludeExtensions = new ArrayList<>(); + if (includeExcludeExtensions != null) { + this.includeExcludeExtensions.addAll(includeExcludeExtensions); + } + } + + /** + * Returns whether or not the fileopt option (and subsequent file extension + * filtering) should be enabled. + * + * @return Whether or not the fileopt option (and subsequent file extension + * filtering) should be enabled. + */ + public boolean hasFileOptOption() { + return fileOptOption; + } + + /** + * Returns whether or not the fileopt option (and subsequent file extension + * filtering) should be enabled. + * + * @param fileOptOption Whether or not the fileopt option (and subsequent + * file extension filtering) should be enabled. + */ + public void setFileOptOption(boolean fileOptOption) { + this.fileOptOption = fileOptOption; + } + + /** + * If the hasFileOptOption is true, this determines whether + * includeExcludeExtensions will be included in the results (excluding all + * others) or includeExcludeExtensions will be excluded from results + * (including all others). + * + * @return Whether to include or exclude includeExcludeExtensions. + */ + public boolean isIncludeElseExclude() { + return includeElseExclude; + } + + /** + * Sets whether or not to include or exclude files. If the hasFileOptOption + * is true, this determines whether includeExcludeExtensions will be + * included in the results (excluding all others) or + * includeExcludeExtensions will be excluded from results (including all + * others). + * + * @param includeElseExclude Whether to include or exclude + * includeExcludeExtensions. + */ + public void setIncludeElseExclude(boolean includeElseExclude) { + this.includeElseExclude = includeElseExclude; + } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index 9e0283e7f6..26e6f8763c 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -1,6 +1,15 @@
+ + + + + + + + + @@ -16,16 +25,27 @@ - - + - - - + + + + + + + + + + + + + + + + - - + @@ -36,7 +56,11 @@ - + + + + + @@ -60,6 +84,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 2f8d8f10ae..7b70511b6c 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -18,6 +18,11 @@ */ package org.sleuthkit.autopsy.modules.photoreccarver; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.lang.StringUtils; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; @@ -26,7 +31,8 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel { - + private static final String EXTENSION_LIST_SEPARATOR = ","; + /** * Instantiate the ingest job settings panel. * @@ -43,13 +49,42 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe * @param settings The ingest job settings. */ private void customizeComponents(PhotoRecCarverIngestJobSettings settings) { + includeExcludeCheckbox.setSelected(settings.hasFileOptOption()); + extensionListTextfield.setText(String.join(EXTENSION_LIST_SEPARATOR, settings.getIncludeExcludeExtensions())); + includeRadioButton.setSelected(!settings.isIncludeElseExclude()); + excludeRadioButton.setSelected(!settings.isIncludeElseExclude()); keepCorruptedFilesCheckbox.setSelected(settings.isKeepCorruptedFiles()); + setIncludePanelEnabled(); + } + + private void setIncludePanelEnabled() { + setIncludePanelEnabled(includeExcludeCheckbox.isSelected()); + } + + private void setIncludePanelEnabled(boolean enabled) { + extensionListTextfield.setEnabled(enabled); + includeRadioButton.setEnabled(enabled); + excludeRadioButton.setEnabled(enabled); } @Override public IngestModuleIngestJobSettings getSettings() { - return new PhotoRecCarverIngestJobSettings( - keepCorruptedFilesCheckbox.isSelected()); + return new PhotoRecCarverIngestJobSettings( + keepCorruptedFilesCheckbox.isSelected(), + includeExcludeCheckbox.isSelected(), + includeRadioButton.isSelected(), + getExtensions(extensionListTextfield.getText())); + } + + private List getExtensions(String combinedList) { + if (StringUtils.isBlank(combinedList)) { + return Collections.emptyList(); + } + + return Stream.of(combinedList.split(EXTENSION_LIST_SEPARATOR)) + .map(ext -> ext.trim().replaceAll(EXTENSION_LIST_SEPARATOR, "")) + .filter(ext -> StringUtils.isNotBlank(ext)) + .collect(Collectors.toList()); } /** @@ -61,26 +96,91 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe // //GEN-BEGIN:initComponents private void initComponents() { + includeExcludeButtonGroup = new javax.swing.ButtonGroup(); keepCorruptedFilesCheckbox = new javax.swing.JCheckBox(); - detectionSettingsLabel = new javax.swing.JLabel(); + javax.swing.JLabel detectionSettingsLabel = new javax.swing.JLabel(); + includeExcludeCheckbox = new javax.swing.JCheckBox(); + javax.swing.JPanel includeExcludeParentPanel = new javax.swing.JPanel(); + includeRadioButton = new javax.swing.JRadioButton(); + excludeRadioButton = new javax.swing.JRadioButton(); + javax.swing.JLabel includeExcludeExtensionsLabel = new javax.swing.JLabel(); + extensionListTextfield = new javax.swing.JTextField(); + + setPreferredSize(null); org.openide.awt.Mnemonics.setLocalizedText(keepCorruptedFilesCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text")); // NOI18N detectionSettingsLabel.setFont(detectionSettingsLabel.getFont().deriveFont(detectionSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD)); org.openide.awt.Mnemonics.setLocalizedText(detectionSettingsLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(includeExcludeCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text")); // NOI18N + includeExcludeCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + includeExcludeCheckboxActionPerformed(evt); + } + }); + + includeExcludeParentPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + + includeExcludeButtonGroup.add(includeRadioButton); + includeRadioButton.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(includeExcludeExtensionsLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeExcludeExtensionsLabel.text")); // NOI18N + + extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N + + javax.swing.GroupLayout includeExcludeParentPanelLayout = new javax.swing.GroupLayout(includeExcludeParentPanel); + includeExcludeParentPanel.setLayout(includeExcludeParentPanelLayout); + includeExcludeParentPanelLayout.setHorizontalGroup( + includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() + .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(includeRadioButton) + .addComponent(excludeRadioButton) + .addComponent(includeExcludeExtensionsLabel)) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + includeExcludeParentPanelLayout.setVerticalGroup( + includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(includeRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(excludeRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(includeExcludeExtensionsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(keepCorruptedFilesCheckbox)) - .addComponent(detectionSettingsLabel)) - .addContainerGap(159, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(detectionSettingsLabel) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(includeExcludeCheckbox) + .addComponent(keepCorruptedFilesCheckbox))))) + .addGroup(layout.createSequentialGroup() + .addGap(35, 35, 35) + .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(190, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -89,12 +189,24 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addComponent(detectionSettingsLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(keepCorruptedFilesCheckbox) - .addContainerGap(145, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(includeExcludeCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(26, Short.MAX_VALUE)) ); }// //GEN-END:initComponents + private void includeExcludeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_includeExcludeCheckboxActionPerformed + setIncludePanelEnabled(); + }//GEN-LAST:event_includeExcludeCheckboxActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel detectionSettingsLabel; + private javax.swing.JRadioButton excludeRadioButton; + private javax.swing.JTextField extensionListTextfield; + private javax.swing.ButtonGroup includeExcludeButtonGroup; + private javax.swing.JCheckBox includeExcludeCheckbox; + private javax.swing.JRadioButton includeRadioButton; private javax.swing.JCheckBox keepCorruptedFilesCheckbox; // End of variables declaration//GEN-END:variables } From f574233895e9d4648b3199349b33168d585a14b7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 31 Jul 2020 08:19:00 -0400 Subject: [PATCH 04/22] some fixes --- .../modules/photoreccarver/Bundle.properties | 2 +- .../photoreccarver/Bundle.properties-MERGED | 5 + .../PhotoRecCarverFileIngestModule.java | 106 +++++++++--------- .../PhotoRecCarverIngestJobSettings.java | 4 +- .../PhotoRecCarverIngestJobSettingsPanel.form | 20 ++-- .../PhotoRecCarverIngestJobSettingsPanel.java | 17 +-- 6 files changed, 79 insertions(+), 75 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties index 629113188e..a700ac239b 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties @@ -21,6 +21,6 @@ PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settin PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Include or Exclude File Extensions PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude -PhotoRecCarverIngestJobSettingsPanel.includeExcludeExtensionsLabel.text=Extensions to exclude / include (a comma-separated list) PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text= PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include +PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Extensions to exclude / include (a comma-separated list) 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..eb14e0af89 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -26,5 +26,10 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files +PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Include or Exclude File Extensions +PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude +PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text= +PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include +PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Extensions to exclude / include (a comma-separated list) unallocatedSpaceProcessingSettingsError.message=The selected file ingest filter ignores unallocated space. This module carves unallocated space. Please choose a filter which does not ignore unallocated space or disable this module. unsupportedOS.message=PhotoRec module is supported on Windows platforms only. diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java index 3f89d84801..abeb9199ba 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverFileIngestModule.java @@ -82,8 +82,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { static final boolean DEFAULT_CONFIG_KEEP_CORRUPTED_FILES = false; static final boolean DEFAULT_CONFIG_FILE_OPT_OPTIONS = false; static final boolean DEFAULT_CONFIG_INCLUDE_ELSE_EXCLUDE = false; - - + private static final String PHOTOREC_DIRECTORY = "photorec_exec"; //NON-NLS private static final String PHOTOREC_SUBDIRECTORY = "bin"; //NON-NLS private static final String PHOTOREC_EXECUTABLE = "photorec_win.exe"; //NON-NLS @@ -103,23 +102,65 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { private File executableFile; private IngestServices services; private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities(); - private final PhotoRecCarverIngestJobSettings settings; + private final String optionsString; private long jobId; - private static class IngestJobTotals { + private final AtomicLong totalItemsRecovered = new AtomicLong(0); private final AtomicLong totalItemsWithErrors = new AtomicLong(0); private final AtomicLong totalWritetime = new AtomicLong(0); private final AtomicLong totalParsetime = new AtomicLong(0); } + /** * Create a PhotoRec Carver ingest module instance. - * + * * @param settings Ingest job settings used to configure the module. */ PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) { - this.settings = settings; + this.optionsString = getPhotorecOptions(settings); + } + + /** + * Creates a photorec command line options string based on the settings. + * + * @param settings The settings. + * + * @return The options string to be provided to Photorec on the command + * line. + */ + private String getPhotorecOptions(PhotoRecCarverIngestJobSettings settings) { + List toRet = new ArrayList(); + + if (settings.isKeepCorruptedFiles()) { + toRet.addAll(Arrays.asList("options", "keep_corrupted_file")); + } + + if (settings.hasFileOptOption()) { + // add the file opt menu item + toRet.add("fileopt"); + + String enable = "enable"; + String disable = "disable"; + + // if we are including file extensions, then we are excluding + // everything else and vice-versa. + String everythingEnable = settings.isIncludeElseExclude() + ? disable : enable; + + toRet.addAll(Arrays.asList("everything", everythingEnable)); + + final String itemEnable = settings.isIncludeElseExclude() + ? enable : disable; + + settings.getIncludeExcludeExtensions().forEach((extension) -> { + toRet.addAll(Arrays.asList(extension, itemEnable)); + }); + } + + toRet.add("search"); + return String.join(",", toRet); } private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) { @@ -156,7 +197,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { this.rootOutputDirPath = createModuleOutputDirectoryForCase(); //Set photorec executable directory based on operating system. - executableFile = locateExecutable(); + executableFile = locateExecutable(); if (PhotoRecCarverFileIngestModule.refCounter.incrementAndGet(this.jobId) == 1) { try { @@ -181,42 +222,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { } } } - - - - private String getPhotorecOptions() { - List toRet = new ArrayList(); - - if (settings.hasFileOptOption()) { - String enable = "enable"; - String disable = "disable"; - - // if we are including file extensions, then we are excluding - // everything else and vice-versa. - String everythingEnable = settings.isIncludeElseExclude() ? - disable : enable; - - toRet.addAll(Arrays.asList("everything", everythingEnable)); - - final String itemEnable = settings.isIncludeElseExclude() ? - enable : disable; - - settings.getIncludeExcludeExtensions().forEach((extension) -> { - toRet.addAll(Arrays.asList(extension, itemEnable)); - }); - } - - if (settings.isKeepCorruptedFiles()) { - toRet.add("keep_corrupted_file"); - } - - if (toRet.size() > 0) { - toRet.add(0, "options"); - } - - toRet.add("search"); - return String.join(",", toRet); - } /** * @inheritDoc @@ -282,10 +287,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE, "/cmd", // NON-NLS tempFilePath.toFile().toString()); - - String photorecOptions = getPhotorecOptions(); - processAndSettings.command().add(photorecOptions); - + + processAndSettings.command().add(this.optionsString); + // Add environment variable to force PhotoRec to run with the same permissions Autopsy uses processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS processAndSettings.redirectErrorStream(true); @@ -493,7 +497,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { return path; } - /** * Finds and returns the path to the executable, if able. * @@ -515,9 +518,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { File usrLocalBin = new File("/usr/local/bin/photorec"); if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) { photorec_linux_directory = "/usr/bin"; - }else if(usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()){ + } else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) { photorec_linux_directory = "/usr/local/bin"; - }else{ + } else { throw new IngestModule.IngestModuleException("Photorec not found"); } execName = Paths.get(photorec_linux_directory, PHOTOREC_LINUX_EXECUTABLE); @@ -527,8 +530,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule { if (null == exeFile) { throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message()); } - - + if (!exeFile.canExecute()) { throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message()); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java index d87984fc94..6ef3035be3 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java @@ -95,7 +95,9 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @return The extension names. */ public List getIncludeExcludeExtensions() { - return Collections.unmodifiableList(includeExcludeExtensions); + return includeExcludeExtensions == null ? + Collections.emptyList() : + Collections.unmodifiableList(includeExcludeExtensions); } /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index 26e6f8763c..4ce6bc15e8 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -5,11 +5,6 @@ - - - - - @@ -122,7 +117,7 @@ - + @@ -140,7 +135,7 @@ - + @@ -162,21 +157,20 @@ + + + - + - + - - - - diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 7b70511b6c..137e5195e6 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -62,9 +62,10 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe } private void setIncludePanelEnabled(boolean enabled) { - extensionListTextfield.setEnabled(enabled); includeRadioButton.setEnabled(enabled); excludeRadioButton.setEnabled(enabled); + extensionListLabel.setEnabled(enabled); + extensionListTextfield.setEnabled(enabled); } @Override @@ -103,11 +104,9 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe javax.swing.JPanel includeExcludeParentPanel = new javax.swing.JPanel(); includeRadioButton = new javax.swing.JRadioButton(); excludeRadioButton = new javax.swing.JRadioButton(); - javax.swing.JLabel includeExcludeExtensionsLabel = new javax.swing.JLabel(); + extensionListLabel = new javax.swing.JLabel(); extensionListTextfield = new javax.swing.JTextField(); - setPreferredSize(null); - org.openide.awt.Mnemonics.setLocalizedText(keepCorruptedFilesCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text")); // NOI18N detectionSettingsLabel.setFont(detectionSettingsLabel.getFont().deriveFont(detectionSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD)); @@ -126,9 +125,10 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe includeRadioButton.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text")); // NOI18N + includeExcludeButtonGroup.add(excludeRadioButton); org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(includeExcludeExtensionsLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeExcludeExtensionsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(extensionListLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text")); // NOI18N extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N @@ -143,7 +143,7 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(includeRadioButton) .addComponent(excludeRadioButton) - .addComponent(includeExcludeExtensionsLabel)) + .addComponent(extensionListLabel)) .addGap(0, 0, Short.MAX_VALUE)) .addComponent(extensionListTextfield, javax.swing.GroupLayout.Alignment.TRAILING)) .addContainerGap()) @@ -156,7 +156,7 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(excludeRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(includeExcludeExtensionsLabel) + .addComponent(extensionListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) @@ -203,6 +203,7 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton excludeRadioButton; + private javax.swing.JLabel extensionListLabel; private javax.swing.JTextField extensionListTextfield; private javax.swing.ButtonGroup includeExcludeButtonGroup; private javax.swing.JCheckBox includeExcludeCheckbox; From 4ae8405c89ddad762cd38ad03944815ff4734979 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 3 Aug 2020 10:28:32 -0400 Subject: [PATCH 05/22] updated look and feel with url --- .../modules/photoreccarver/Bundle.properties | 11 +- .../photoreccarver/Bundle.properties-MERGED | 11 +- .../PhotoRecCarverIngestJobSettingsPanel.form | 78 +++++----- .../PhotoRecCarverIngestJobSettingsPanel.java | 139 +++++++++++++----- 4 files changed, 159 insertions(+), 80 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties index a700ac239b..39cc41e1f4 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties @@ -19,8 +19,11 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files -PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Include or Exclude File Extensions -PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude +PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types +PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesHyperlink.text=https://www.cgsecurity.org/wiki/\nFile_Formats_Recovered_By_PhotoRec +PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types: +PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text= -PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include -PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Extensions to exclude / include (a comma-separated list) +PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Types (comma separated list of extensions) +PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Ignore the specified types +PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Carve only the specified types 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 eb14e0af89..f1725a18fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -26,10 +26,13 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files -PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Include or Exclude File Extensions -PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude +PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types +PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesHyperlink.text=https://www.cgsecurity.org/wiki/\nFile_Formats_Recovered_By_PhotoRec +PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types: +PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text= -PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include -PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Extensions to exclude / include (a comma-separated list) +PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Types (comma separated list of extensions) +PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Ignore the specified types +PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Carve only the specified types unallocatedSpaceProcessingSettingsError.message=The selected file ingest filter ignores unallocated space. This module carves unallocated space. Please choose a filter which does not ignore unallocated space or disable this module. unsupportedOS.message=PhotoRec module is supported on Windows platforms only. diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index 4ce6bc15e8..0e51274e04 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -21,26 +21,13 @@ + - - - - - - - - - - - - - - - - - + + + + - @@ -49,13 +36,12 @@ - + - + - @@ -113,32 +99,35 @@ - - - - - - - - - + + + + + + + - + - - + - + + + + + + + @@ -179,6 +168,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 137e5195e6..84511b0a52 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -18,21 +18,34 @@ */ package org.sleuthkit.autopsy.modules.photoreccarver; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Desktop; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.List; +import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang.StringUtils; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; /** * Ingest job settings panel for the Encryption Detection module. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel { + + private static final Logger logger = Logger.getLogger(PhotoRecCarverIngestJobSettingsPanel.class.getName()); private static final String EXTENSION_LIST_SEPARATOR = ","; - + private static final String PHOTOREC_TYPES_URL = "https://www.cgsecurity.org/wiki/File_Formats_Recovered_By_PhotoRec"; + /** * Instantiate the ingest job settings panel. * @@ -54,36 +67,78 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe includeRadioButton.setSelected(!settings.isIncludeElseExclude()); excludeRadioButton.setSelected(!settings.isIncludeElseExclude()); keepCorruptedFilesCheckbox.setSelected(settings.isKeepCorruptedFiles()); + setupTypesHyperlink(); setIncludePanelEnabled(); } - + + /** + * Sets up a clickable hyperlink for the different supported types for + * extensions. + */ + private void setupTypesHyperlink() { + // taken from https://www.codejava.net/java-se/swing/how-to-create-hyperlink-with-jlabel-in-java-swing + this.fullListOfTypesHyperlink.setForeground(Color.BLUE.darker()); + this.fullListOfTypesHyperlink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + this.fullListOfTypesHyperlink.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(PHOTOREC_TYPES_URL)); + } catch (IOException | URISyntaxException ex) { + logger.log(Level.WARNING, "There was an error going to types huperlink: " + PHOTOREC_TYPES_URL, ex); + } + } + }); + + } + + /** + * Whether or not the file type inclusion/exclusion panel should be enabled + * based on whether or not the includeExcludeCheckbox is checked. + */ private void setIncludePanelEnabled() { setIncludePanelEnabled(includeExcludeCheckbox.isSelected()); } - + + /** + * Sets components in the inclusion/exclusion panel to the specified enabled + * state. + * + * @param enabled Whether or not to enable components. + */ private void setIncludePanelEnabled(boolean enabled) { includeRadioButton.setEnabled(enabled); excludeRadioButton.setEnabled(enabled); extensionListLabel.setEnabled(enabled); extensionListTextfield.setEnabled(enabled); + exampleLabel.setEnabled(enabled); + fullListOfTypesLabel.setEnabled(enabled); } @Override public IngestModuleIngestJobSettings getSettings() { - return new PhotoRecCarverIngestJobSettings( - keepCorruptedFilesCheckbox.isSelected(), - includeExcludeCheckbox.isSelected(), - includeRadioButton.isSelected(), - getExtensions(extensionListTextfield.getText())); + return new PhotoRecCarverIngestJobSettings( + keepCorruptedFilesCheckbox.isSelected(), + includeExcludeCheckbox.isSelected(), + includeRadioButton.isSelected(), + getExtensions(extensionListTextfield.getText())); } - + + /** + * Determines a list of extensions to pass as parameters to photorec based + * on the specified input. Splits on separator and trims. + * + * @param combinedList The comma-separated list. + * + * @return The list of strings to use with photorec. + */ private List getExtensions(String combinedList) { if (StringUtils.isBlank(combinedList)) { return Collections.emptyList(); } - + return Stream.of(combinedList.split(EXTENSION_LIST_SEPARATOR)) - .map(ext -> ext.trim().replaceAll(EXTENSION_LIST_SEPARATOR, "")) + .map(ext -> ext.trim()) .filter(ext -> StringUtils.isNotBlank(ext)) .collect(Collectors.toList()); } @@ -106,6 +161,9 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe excludeRadioButton = new javax.swing.JRadioButton(); extensionListLabel = new javax.swing.JLabel(); extensionListTextfield = new javax.swing.JTextField(); + exampleLabel = new javax.swing.JLabel(); + fullListOfTypesLabel = new javax.swing.JLabel(); + fullListOfTypesHyperlink = new javax.swing.JLabel(); org.openide.awt.Mnemonics.setLocalizedText(keepCorruptedFilesCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text")); // NOI18N @@ -132,6 +190,12 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(exampleLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(fullListOfTypesLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(fullListOfTypesHyperlink, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesHyperlink.text")); // NOI18N + javax.swing.GroupLayout includeExcludeParentPanelLayout = new javax.swing.GroupLayout(includeExcludeParentPanel); includeExcludeParentPanel.setLayout(includeExcludeParentPanelLayout); includeExcludeParentPanelLayout.setHorizontalGroup( @@ -139,26 +203,31 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() - .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(includeRadioButton) - .addComponent(excludeRadioButton) - .addComponent(extensionListLabel)) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(extensionListTextfield, javax.swing.GroupLayout.Alignment.TRAILING)) - .addContainerGap()) + .addComponent(fullListOfTypesLabel) + .addComponent(exampleLabel) + .addComponent(extensionListLabel) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(includeRadioButton) + .addComponent(excludeRadioButton)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); includeExcludeParentPanelLayout.setVerticalGroup( includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(includeRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(0, 0, 0) .addComponent(excludeRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(extensionListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(exampleLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fullListOfTypesLabel) + .addGap(0, 0, 0) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.DEFAULT_SIZE, 36, Short.MAX_VALUE) .addContainerGap()) ); @@ -167,33 +236,24 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(detectionSettingsLabel) - .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(includeExcludeCheckbox) - .addComponent(keepCorruptedFilesCheckbox))))) - .addGroup(layout.createSequentialGroup() - .addGap(35, 35, 35) - .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(190, Short.MAX_VALUE)) + .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(detectionSettingsLabel) + .addComponent(keepCorruptedFilesCheckbox) + .addComponent(includeExcludeCheckbox))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(detectionSettingsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(0, 2, 2) .addComponent(keepCorruptedFilesCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(0, 0, 0) .addComponent(includeExcludeCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(26, Short.MAX_VALUE)) + .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// //GEN-END:initComponents @@ -202,9 +262,12 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe }//GEN-LAST:event_includeExcludeCheckboxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel exampleLabel; private javax.swing.JRadioButton excludeRadioButton; private javax.swing.JLabel extensionListLabel; private javax.swing.JTextField extensionListTextfield; + private javax.swing.JLabel fullListOfTypesHyperlink; + private javax.swing.JLabel fullListOfTypesLabel; private javax.swing.ButtonGroup includeExcludeButtonGroup; private javax.swing.JCheckBox includeExcludeCheckbox; private javax.swing.JRadioButton includeRadioButton; From 1a2b5085f063a51a51c2ce586e465a8266235133 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 3 Aug 2020 12:40:05 -0400 Subject: [PATCH 06/22] updated panel --- .../PhotoRecCarverIngestJobSettingsPanel.form | 204 ++++++++---------- .../PhotoRecCarverIngestJobSettingsPanel.java | 97 ++++----- 2 files changed, 131 insertions(+), 170 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index 0e51274e04..476773e08f 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -21,13 +21,29 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -38,10 +54,23 @@ - + - + + + + + + + + + + + + + + @@ -80,116 +109,61 @@ - + - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 84511b0a52..35fe58ab00 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -156,14 +156,13 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe keepCorruptedFilesCheckbox = new javax.swing.JCheckBox(); javax.swing.JLabel detectionSettingsLabel = new javax.swing.JLabel(); includeExcludeCheckbox = new javax.swing.JCheckBox(); - javax.swing.JPanel includeExcludeParentPanel = new javax.swing.JPanel(); - includeRadioButton = new javax.swing.JRadioButton(); excludeRadioButton = new javax.swing.JRadioButton(); - extensionListLabel = new javax.swing.JLabel(); - extensionListTextfield = new javax.swing.JTextField(); exampleLabel = new javax.swing.JLabel(); fullListOfTypesLabel = new javax.swing.JLabel(); + extensionListLabel = new javax.swing.JLabel(); fullListOfTypesHyperlink = new javax.swing.JLabel(); + extensionListTextfield = new javax.swing.JTextField(); + includeRadioButton = new javax.swing.JRadioButton(); org.openide.awt.Mnemonics.setLocalizedText(keepCorruptedFilesCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text")); // NOI18N @@ -177,71 +176,46 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe } }); - includeExcludeParentPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - - includeExcludeButtonGroup.add(includeRadioButton); - includeRadioButton.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text")); // NOI18N - includeExcludeButtonGroup.add(excludeRadioButton); org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(extensionListLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text")); // NOI18N - - extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(exampleLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(fullListOfTypesLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(extensionListLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(fullListOfTypesHyperlink, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesHyperlink.text")); // NOI18N - javax.swing.GroupLayout includeExcludeParentPanelLayout = new javax.swing.GroupLayout(includeExcludeParentPanel); - includeExcludeParentPanel.setLayout(includeExcludeParentPanelLayout); - includeExcludeParentPanelLayout.setHorizontalGroup( - includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(fullListOfTypesLabel) - .addComponent(exampleLabel) - .addComponent(extensionListLabel) - .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(includeRadioButton) - .addComponent(excludeRadioButton)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - includeExcludeParentPanelLayout.setVerticalGroup( - includeExcludeParentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(includeExcludeParentPanelLayout.createSequentialGroup() - .addComponent(includeRadioButton) - .addGap(0, 0, 0) - .addComponent(excludeRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extensionListLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(exampleLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fullListOfTypesLabel) - .addGap(0, 0, 0) - .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.DEFAULT_SIZE, 36, Short.MAX_VALUE) - .addContainerGap()) - ); + extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N + + includeExcludeButtonGroup.add(includeRadioButton); + includeRadioButton.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(detectionSettingsLabel) - .addComponent(keepCorruptedFilesCheckbox) - .addComponent(includeExcludeCheckbox))) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(detectionSettingsLabel) + .addComponent(keepCorruptedFilesCheckbox) + .addComponent(includeExcludeCheckbox))) + .addGroup(layout.createSequentialGroup() + .addGap(16, 16, 16) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(includeRadioButton) + .addComponent(excludeRadioButton) + .addComponent(exampleLabel) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(fullListOfTypesLabel) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(extensionListLabel)))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -250,10 +224,23 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addComponent(detectionSettingsLabel) .addGap(0, 2, 2) .addComponent(keepCorruptedFilesCheckbox) - .addGap(0, 0, 0) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(includeExcludeCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(includeExcludeParentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(includeRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(excludeRadioButton) + .addGap(4, 4, 4) + .addComponent(extensionListLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(exampleLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fullListOfTypesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fullListOfTypesHyperlink) + .addContainerGap()) ); }// //GEN-END:initComponents From 065650fe401a9e48a4c9f711b2e7ee294db671c5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 3 Aug 2020 14:40:12 -0400 Subject: [PATCH 07/22] UI indent updates --- .../PhotoRecCarverIngestJobSettingsPanel.form | 39 ++++++++----------- .../PhotoRecCarverIngestJobSettingsPanel.java | 31 +++++++-------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index 476773e08f..f067266970 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -20,30 +20,25 @@ - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 35fe58ab00..75986ba67f 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -198,24 +198,21 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(detectionSettingsLabel) - .addComponent(keepCorruptedFilesCheckbox) - .addComponent(includeExcludeCheckbox))) - .addGroup(layout.createSequentialGroup() - .addGap(16, 16, 16) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(includeRadioButton) - .addComponent(excludeRadioButton) - .addComponent(exampleLabel) - .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(fullListOfTypesLabel) - .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(extensionListLabel)))) - .addContainerGap()) + .addComponent(detectionSettingsLabel) + .addComponent(keepCorruptedFilesCheckbox) + .addComponent(includeExcludeCheckbox))) + .addGroup(layout.createSequentialGroup() + .addGap(31, 31, 31) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(includeRadioButton) + .addComponent(excludeRadioButton) + .addComponent(exampleLabel) + .addComponent(extensionListTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(fullListOfTypesLabel) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(extensionListLabel))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) From 3183c8800e7946957cda31ef117c73714e41c644 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 3 Aug 2020 15:26:39 -0400 Subject: [PATCH 08/22] formatting --- .../photoreccarver/PhotoRecCarverIngestJobSettings.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java index 6ef3035be3..9bb211f406 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java @@ -95,9 +95,9 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @return The extension names. */ public List getIncludeExcludeExtensions() { - return includeExcludeExtensions == null ? - Collections.emptyList() : - Collections.unmodifiableList(includeExcludeExtensions); + return includeExcludeExtensions == null + ? Collections.emptyList() + : Collections.unmodifiableList(includeExcludeExtensions); } /** From 5565d7e6d30914f936f42ab336fbf25e4ebe4aa5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 4 Aug 2020 10:10:24 -0400 Subject: [PATCH 09/22] updated settings methods to packaged private --- .../PhotoRecCarverIngestJobSettings.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java index 9bb211f406..40e929cb75 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettings.java @@ -58,7 +58,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @param includeExcludeExtensions The extensions to include or exclude * (i.e. jpg, gif) */ - public PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles, boolean fileOptOption, boolean includeElseExclude, List includeExcludeExtensions) { + PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles, boolean fileOptOption, boolean includeElseExclude, List includeExcludeExtensions) { this.keepCorruptedFiles = keepCorruptedFiles; this.fileOptOption = fileOptOption; this.includeElseExclude = includeElseExclude; @@ -94,7 +94,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * * @return The extension names. */ - public List getIncludeExcludeExtensions() { + List getIncludeExcludeExtensions() { return includeExcludeExtensions == null ? Collections.emptyList() : Collections.unmodifiableList(includeExcludeExtensions); @@ -106,7 +106,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * * @param includeExcludeExtensions The extension names. */ - public void setIncludeExcludeExtensions(List includeExcludeExtensions) { + void setIncludeExcludeExtensions(List includeExcludeExtensions) { this.includeExcludeExtensions = new ArrayList<>(); if (includeExcludeExtensions != null) { this.includeExcludeExtensions.addAll(includeExcludeExtensions); @@ -120,7 +120,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @return Whether or not the fileopt option (and subsequent file extension * filtering) should be enabled. */ - public boolean hasFileOptOption() { + boolean hasFileOptOption() { return fileOptOption; } @@ -131,7 +131,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @param fileOptOption Whether or not the fileopt option (and subsequent * file extension filtering) should be enabled. */ - public void setFileOptOption(boolean fileOptOption) { + void setFileOptOption(boolean fileOptOption) { this.fileOptOption = fileOptOption; } @@ -143,7 +143,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * * @return Whether to include or exclude includeExcludeExtensions. */ - public boolean isIncludeElseExclude() { + boolean isIncludeElseExclude() { return includeElseExclude; } @@ -157,7 +157,7 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett * @param includeElseExclude Whether to include or exclude * includeExcludeExtensions. */ - public void setIncludeElseExclude(boolean includeElseExclude) { + void setIncludeElseExclude(boolean includeElseExclude) { this.includeElseExclude = includeElseExclude; } } From b3e7a33f8bb11bbc8f6e22d4b469a22759cea920 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 4 Aug 2020 14:30:31 -0400 Subject: [PATCH 10/22] Added code to widen the subject column in the message viewer thread table --- .../autopsy/communications/Utils.java | 27 +++++++++++++++++++ .../relationships/Bundle.properties-MERGED | 2 +- .../relationships/MessageViewer.java | 10 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Utils.java b/Core/src/org/sleuthkit/autopsy/communications/Utils.java index 4a3e03e1f2..3309bab92e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Utils.java +++ b/Core/src/org/sleuthkit/autopsy/communications/Utils.java @@ -18,9 +18,12 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Component; import java.time.ZoneId; import java.time.ZoneOffset; import java.util.TimeZone; +import javax.swing.table.TableCellRenderer; +import org.netbeans.swing.outline.Outline; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; import org.sleuthkit.datamodel.Account; @@ -47,5 +50,29 @@ public final class Utils { static public final String getIconFilePath(Account.Type type) { return Accounts.getIconFilePath(type); } + + static public void setColumnWidths(Outline outline) { + int margin = 4; + int padding = 8; + + final int rows = Math.min(100, outline.getRowCount()); + + for (int column = 0; column < outline.getColumnCount(); column++) { + int columnWidthLimit = 500; + int columnWidth = 0; + + // find the maximum width needed to fit the values for the first 100 rows, at most + for (int row = 0; row < rows; row++) { + TableCellRenderer renderer = outline.getCellRenderer(row, column); + Component comp = outline.prepareRenderer(renderer, row, column); + columnWidth = Math.max(comp.getPreferredSize().width, columnWidth); + } + + columnWidth += 2 * margin + padding; // add margin and regular padding + columnWidth = Math.min(columnWidth, columnWidthLimit); + + outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED index 6778d8dc53..616408978d 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED @@ -73,5 +73,5 @@ SummaryViewer.referencesLabel.text=Communication References: SummaryViewer.referencesDataLabel.text= SummaryViewer.contactsLabel.text=Book Entries: SummaryViewer.accountCountry.text= -SummaryViewer.fileRefPane.border.title=File Referernce(s) in Current Case +SummaryViewer.fileRefPane.border.title=File References in Current Case SummaryViewer.selectAccountFileRefLabel.text= diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleSettingsPanel.java index e804e0bea7..1453ad80e7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleSettingsPanel.java @@ -18,14 +18,17 @@ */ package org.sleuthkit.autopsy.modules.hashdatabase; +import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; +import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumn; import org.apache.commons.lang.StringUtils; import org.sleuthkit.autopsy.coreutils.Logger; @@ -78,6 +81,7 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe if (i == 0) { column.setPreferredWidth(((int) (width1 * 0.07))); } else { + column.setCellRenderer(new HashSetTableCellRenderer()); column.setPreferredWidth(((int) (width1 * 0.92))); } } @@ -225,6 +229,24 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe return valid; } } + + /** + * Simple TableCellRenderer to add tool tips to the cells + */ + private static final class HashSetTableCellRenderer extends DefaultTableCellRenderer{ + + private static final long serialVersionUID = 1L; + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + label.setToolTipText(label.getText()); + return label; + } + + } private static final class HashSetsTableModel extends AbstractTableModel { diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesIdentifierIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesIdentifierIngestJobSettingsPanel.java index 70aa5c4795..b9cade0f53 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesIdentifierIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesIdentifierIngestJobSettingsPanel.java @@ -18,13 +18,16 @@ */ package org.sleuthkit.autopsy.modules.interestingitems; +import java.awt.Component; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.TreeMap; +import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumn; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @@ -110,6 +113,7 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS if (i == 0) { column.setPreferredWidth(((int) (width * 0.07))); } else { + column.setCellRenderer(new FileSetsTableCellRenderer()); column.setPreferredWidth(((int) (width * 0.92))); } } @@ -158,6 +162,24 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS // Cache the snapshot so it will be avaialble for the next update. this.filesSetSnapshot = newFilesSetSnapshot; } + + /** + * Simple TableCellRenderer to add tool tips to cells. + */ + private static final class FileSetsTableCellRenderer extends DefaultTableCellRenderer { + + private static final long serialVersionUID = 1L; + + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + label.setToolTipText(label.getText()); + return label; + } + } /** * Table model for a JTable component that allows users to enable and diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 79a4135ce4..7dfb0acb54 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/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchJobSettingsPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchJobSettingsPanel.java index 379a4b37bd..ae8797b992 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchJobSettingsPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchJobSettingsPanel.java @@ -18,15 +18,18 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumn; import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; @@ -81,6 +84,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe if (i == 0) { column.setPreferredWidth(((int) (width * 0.07))); } else { + column.setCellRenderer(new KeywordTableCellRenderer()); column.setPreferredWidth(((int) (width * 0.92))); } } @@ -179,6 +183,25 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe displayEncodings(); tableModel.fireTableDataChanged(); } + + /** + * Simple TableCellRenderer to add tool tips to cells. + */ + private static final class KeywordTableCellRenderer extends DefaultTableCellRenderer{ + + private static final long serialVersionUID = 1L; + + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + label.setToolTipText(label.getText()); + return label; + } + + } private class KeywordListsTableModel extends AbstractTableModel { From b7db91c963e6d09c116a2c214767b97946cd5709 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 6 Aug 2020 17:04:57 -0400 Subject: [PATCH 22/22] Fixed doubling cr hashset issue --- .../HashDatabaseOptionsPanelController.java | 5 +++- .../modules/hashdatabase/HashDbManager.java | 24 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java index 41de451c67..4d15c43bd1 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java @@ -72,7 +72,10 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro */ @Override public void cancel() { - getPanel().cancel(); + if(changed) { + getPanel().cancel(); + changed = false; + } } @Override diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 139edb8ec7..40544c5485 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -326,17 +326,19 @@ public class HashDbManager implements PropertyChangeListener { } // Add the hash database to the collection - hashSets.add(db); - - // Let any external listeners know that there's a new set - try { - changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName); - } catch (Exception e) { - logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS - MessageNotifyUtil.Notify.show( - NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"), - NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"), - MessageNotifyUtil.MessageType.ERROR); + if(!hashSets.contains(db)) { + hashSets.add(db); + + // Let any external listeners know that there's a new set + try { + changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName); + } catch (Exception e) { + logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS + MessageNotifyUtil.Notify.show( + NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"), + NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"), + MessageNotifyUtil.MessageType.ERROR); + } } return db;