updates for extension validation

This commit is contained in:
Greg DiCristofaro 2020-08-04 16:30:16 -04:00
parent 5565d7e6d3
commit 8cd7594afa
5 changed files with 134 additions and 47 deletions

View File

@ -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=<html>https://www.cgsecurity.org/wiki/\nFile_Formats_Recovered_By_PhotoRec</html>
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=

View File

@ -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=<html>https://www.cgsecurity.org/wiki/\nFile_Formats_Recovered_By_PhotoRec</html>
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=

View File

@ -19,6 +19,8 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
@ -36,11 +38,14 @@
<Component id="exampleLabel" min="-2" max="-2" attributes="0"/>
<Component id="extensionListTextfield" min="-2" pref="258" max="-2" attributes="0"/>
<Component id="fullListOfTypesLabel" min="-2" max="-2" attributes="0"/>
<Component id="fullListOfTypesHyperlink" alignment="0" min="-2" pref="250" max="-2" attributes="0"/>
<Component id="extensionListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fullListOfTypesHyperlink" alignment="0" min="-2" pref="238" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
@ -64,8 +69,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="fullListOfTypesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="fullListOfTypesHyperlink" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="fullListOfTypesHyperlink" min="-2" pref="51" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -137,8 +141,17 @@
</Component>
<Component class="javax.swing.JLabel" name="fullListOfTypesHyperlink">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties" key="PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesHyperlink.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="String.format(&quot;&lt;html&gt;%s&lt;/html&gt;&quot;, PHOTOREC_TYPES_URL)" type="code"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[240, 50]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[240, 50]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[240, 50]"/>
</Property>
</Properties>
</Component>

View File

@ -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<String> getAndUpdateExtensions() {
PhotoRecExtensions extensions = getExtensions(extensionListTextfield.getText());
if (extensions.getInvalidExtensions().size() > 0) {
JOptionPane.showMessageDialog(
this,
String.format("<html>%s</html>",
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<String> validExtensions;
private final List<String> invalidExtensions;
/**
* Main constructor.
* @param validExtensions A list of strings representing the valid extensions.
* @param invalidExtensions A list of invalid extensions.
*/
PhotoRecExtensions(List<String> validExtensions, List<String> invalidExtensions) {
this.validExtensions = validExtensions == null ? Collections.emptyList() : Collections.unmodifiableList(validExtensions);
this.invalidExtensions = invalidExtensions == null ? Collections.emptyList() : Collections.unmodifiableList(invalidExtensions);
}
/**
* @return The valid extensions.
*/
List<String> getValidExtensions() {
return validExtensions;
}
/**
* @return The invalid extensions.
*/
List<String> getInvalidExtensions() {
return invalidExtensions;
}
}
/**
@ -132,15 +195,18 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
*
* @return The list of strings to use with photorec.
*/
private List<String> 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<Boolean, List<String>> 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("<html>%s</html>", 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
@ -197,6 +266,8 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -211,8 +282,9 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
.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)))
.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))
);
}// </editor-fold>//GEN-END:initComponents

View File

@ -2,3 +2,5 @@ The 'bin' folder is the version used when running the PhotoRec ingest module. I
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.
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.