diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties index 39cc41e1f4..3a3478ab94 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties @@ -20,7 +20,6 @@ PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files 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= 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 f1725a18fa..3544b97d36 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -8,6 +8,9 @@ OpenIDE-Module-Long-Description=PhotoRec Carver ingest module. \n\n Carves unall OpenIDE-Module-Short-Description=Carves unallocated space and feeds carved files back into the system for processing. moduleDisplayName.text=PhotoRec Carver moduleDescription.text=Runs PhotoRec carver against unallocated space in the data source. +# {0} - extensions +PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_description=The following extensions are invalid and were removed: {0} +PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_title=Invalid Extensions PhotoRecIngestModule.nonHostnameUNCPathUsed=PhotoRec cannot operate with a UNC path containing IP addresses. PhotoRecIngestModule.PermissionsNotSufficient=Insufficient permissions accessing PhotoRecIngestModule.PermissionsNotSufficientSeeReference=See 'Shared Drive Authentication' in Autopsy help. @@ -27,7 +30,6 @@ PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files 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= diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form index f067266970..ca456614c7 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.form @@ -20,25 +20,30 @@ - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -64,8 +69,7 @@ - - + @@ -137,8 +141,17 @@ - - + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java index 75986ba67f..b62218e17f 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/PhotoRecCarverIngestJobSettingsPanel.java @@ -28,10 +28,13 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.swing.JOptionPane; import org.apache.commons.lang.StringUtils; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; import org.sleuthkit.autopsy.coreutils.Logger; @@ -44,7 +47,7 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe 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"; + private static final String PHOTOREC_TYPES_URL = "http://sleuthkit.org/autopsy/docs/user-docs/latest/photorec_carver_page.html"; /** * Instantiate the ingest job settings panel. @@ -116,12 +119,72 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe } @Override + @Messages({ + "PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_title=Invalid Extensions", + "# {0} - extensions", + "PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_description=The following extensions are invalid and were removed: {0}" + }) public IngestModuleIngestJobSettings getSettings() { + + return new PhotoRecCarverIngestJobSettings( keepCorruptedFilesCheckbox.isSelected(), includeExcludeCheckbox.isSelected(), includeRadioButton.isSelected(), - getExtensions(extensionListTextfield.getText())); + getAndUpdateExtensions() + ); + } + + + private List getAndUpdateExtensions() { + PhotoRecExtensions extensions = getExtensions(extensionListTextfield.getText()); + + if (extensions.getInvalidExtensions().size() > 0) { + JOptionPane.showMessageDialog( + this, + String.format("%s", + Bundle.PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_description( + String.join(",", extensions.getInvalidExtensions()))), + Bundle.PhotoRecCarverIngestJobSettingsPanel_getSettings_invalidExtensions_title(), + JOptionPane.ERROR_MESSAGE); + } + + + extensionListTextfield.setText(String.join(EXTENSION_LIST_SEPARATOR, extensions.getValidExtensions())); + return extensions.getValidExtensions(); + } + + /** + * An object defining valid and invalid photorec extensions as provided by the user. + */ + private static class PhotoRecExtensions { + + private final List validExtensions; + private final List invalidExtensions; + + /** + * Main constructor. + * @param validExtensions A list of strings representing the valid extensions. + * @param invalidExtensions A list of invalid extensions. + */ + PhotoRecExtensions(List validExtensions, List invalidExtensions) { + this.validExtensions = validExtensions == null ? Collections.emptyList() : Collections.unmodifiableList(validExtensions); + this.invalidExtensions = invalidExtensions == null ? Collections.emptyList() : Collections.unmodifiableList(invalidExtensions); + } + + /** + * @return The valid extensions. + */ + List getValidExtensions() { + return validExtensions; + } + + /** + * @return The invalid extensions. + */ + List getInvalidExtensions() { + return invalidExtensions; + } } /** @@ -132,15 +195,18 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe * * @return The list of strings to use with photorec. */ - private List getExtensions(String combinedList) { + private PhotoRecExtensions getExtensions(String combinedList) { if (StringUtils.isBlank(combinedList)) { - return Collections.emptyList(); + return new PhotoRecExtensions(null, null); } - return Stream.of(combinedList.split(EXTENSION_LIST_SEPARATOR)) + Map> extensions = Stream.of(combinedList.split(EXTENSION_LIST_SEPARATOR)) .map(ext -> ext.trim()) .filter(ext -> StringUtils.isNotBlank(ext)) - .collect(Collectors.toList()); + .sorted((a, b) -> a.toLowerCase().compareTo(b.toLowerCase())) + .collect(Collectors.partitioningBy(PhotoRecCarverFileOptExtensions::isValidExtension)); + + return new PhotoRecExtensions(extensions.get(true), extensions.get(false)); } /** @@ -185,7 +251,10 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe 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 + org.openide.awt.Mnemonics.setLocalizedText(fullListOfTypesHyperlink, String.format("%s", PHOTOREC_TYPES_URL)); + fullListOfTypesHyperlink.setMaximumSize(new java.awt.Dimension(240, 50)); + fullListOfTypesHyperlink.setMinimumSize(new java.awt.Dimension(240, 50)); + fullListOfTypesHyperlink.setPreferredSize(new java.awt.Dimension(240, 50)); extensionListTextfield.setText(org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text")); // NOI18N @@ -198,21 +267,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) - .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))) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .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(extensionListLabel) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -236,8 +308,7 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(fullListOfTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fullListOfTypesHyperlink) - .addContainerGap()) + .addComponent(fullListOfTypesHyperlink, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// //GEN-END:initComponents diff --git a/thirdparty/photorec_exec/README.txt b/thirdparty/photorec_exec/README.txt index 379000fcde..b65f25d7bd 100644 --- a/thirdparty/photorec_exec/README.txt +++ b/thirdparty/photorec_exec/README.txt @@ -1,4 +1,6 @@ The 'bin' folder is the version used when running the PhotoRec ingest module. It is also the 32-bit version. When the 64-bit version of the installer is created, the photorec_exec/64-bit/bin folder is placed at photorec_exec/bin. When the 32-bit version of the installer is created, the photorec_exec/64-bit folder is deleted. -See 'build-windows-installer.xml' for more details. \ No newline at end of file +See 'build-windows-installer.xml' for more details. + +Extensions for PhotoRec need to be placed in the PhotoRecCarverFileOptExtensions class so that only valid extensions will be used with PhotoRec. It can be generated through PhotoRec by launching photorec_win with no arguments, go to "Proceed", go to "File Opt" and press 'b'. This should generate a photorec.cfg file in the current working directory with a list of all the extensions. \ No newline at end of file