mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Merge pull request #6172 from sleuthkit/develop
Merge develop into data_source_summary_result_viewer
This commit is contained in:
commit
0da9a4dc09
@ -18,9 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.communications;
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.util.TimeZone;
|
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.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
|
import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
@ -47,5 +50,29 @@ public final class Utils {
|
|||||||
static public final String getIconFilePath(Account.Type type) {
|
static public final String getIconFilePath(Account.Type type) {
|
||||||
return Accounts.getIconFilePath(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,5 +73,5 @@ SummaryViewer.referencesLabel.text=Communication References:
|
|||||||
SummaryViewer.referencesDataLabel.text=<reference count>
|
SummaryViewer.referencesDataLabel.text=<reference count>
|
||||||
SummaryViewer.contactsLabel.text=Book Entries:
|
SummaryViewer.contactsLabel.text=Book Entries:
|
||||||
SummaryViewer.accountCountry.text=<account country>
|
SummaryViewer.accountCountry.text=<account country>
|
||||||
SummaryViewer.fileRefPane.border.title=File Referernce(s) in Current Case
|
SummaryViewer.fileRefPane.border.title=File References in Current Case
|
||||||
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
|
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
|
||||||
|
@ -38,6 +38,8 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
|
import javax.swing.event.TableModelEvent;
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
import org.netbeans.swing.outline.Outline;
|
import org.netbeans.swing.outline.Outline;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
@ -50,6 +52,7 @@ import org.openide.nodes.Node.PropertySet;
|
|||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||||
|
import org.sleuthkit.autopsy.communications.Utils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,6 +118,13 @@ final class MessageViewer extends JPanel implements RelationshipsViewer {
|
|||||||
showSelectedThread();
|
showSelectedThread();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rootTablePane.getOutlineView().getOutline().getModel().addTableModelListener(new TableModelListener() {
|
||||||
|
@Override
|
||||||
|
public void tableChanged(TableModelEvent e) {
|
||||||
|
Utils.setColumnWidths(rootTablePane.getOutlineView().getOutline());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
threadMessagesPanel.setChildFactory(threadMessageNodeFactory);
|
threadMessagesPanel.setChildFactory(threadMessageNodeFactory);
|
||||||
|
|
||||||
|
@ -72,7 +72,10 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
getPanel().cancel();
|
if(changed) {
|
||||||
|
getPanel().cancel();
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -326,17 +326,19 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the hash database to the collection
|
// Add the hash database to the collection
|
||||||
hashSets.add(db);
|
if(!hashSets.contains(db)) {
|
||||||
|
hashSets.add(db);
|
||||||
// Let any external listeners know that there's a new set
|
|
||||||
try {
|
// Let any external listeners know that there's a new set
|
||||||
changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName);
|
try {
|
||||||
} catch (Exception e) {
|
changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName);
|
||||||
logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS
|
} catch (Exception e) {
|
||||||
MessageNotifyUtil.Notify.show(
|
logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS
|
||||||
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"),
|
MessageNotifyUtil.Notify.show(
|
||||||
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"),
|
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"),
|
||||||
MessageNotifyUtil.MessageType.ERROR);
|
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"),
|
||||||
|
MessageNotifyUtil.MessageType.ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return db;
|
return db;
|
||||||
|
|
||||||
|
@ -18,14 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.hashdatabase;
|
package org.sleuthkit.autopsy.modules.hashdatabase;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -78,6 +81,7 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
column.setPreferredWidth(((int) (width1 * 0.07)));
|
column.setPreferredWidth(((int) (width1 * 0.07)));
|
||||||
} else {
|
} else {
|
||||||
|
column.setCellRenderer(new HashSetTableCellRenderer());
|
||||||
column.setPreferredWidth(((int) (width1 * 0.92)));
|
column.setPreferredWidth(((int) (width1 * 0.92)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,6 +229,24 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
return valid;
|
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 {
|
private static final class HashSetsTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
@ -18,13 +18,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
@ -110,6 +113,7 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
column.setPreferredWidth(((int) (width * 0.07)));
|
column.setPreferredWidth(((int) (width * 0.07)));
|
||||||
} else {
|
} else {
|
||||||
|
column.setCellRenderer(new FileSetsTableCellRenderer());
|
||||||
column.setPreferredWidth(((int) (width * 0.92)));
|
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.
|
// Cache the snapshot so it will be avaialble for the next update.
|
||||||
this.filesSetSnapshot = newFilesSetSnapshot;
|
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
|
* Table model for a JTable component that allows users to enable and
|
||||||
|
@ -19,3 +19,10 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
|
|||||||
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
||||||
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
||||||
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Types (comma separated list of extensions)
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Ignore the specified types
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Carve only the specified types
|
||||||
|
@ -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.
|
OpenIDE-Module-Short-Description=Carves unallocated space and feeds carved files back into the system for processing.
|
||||||
moduleDisplayName.text=PhotoRec Carver
|
moduleDisplayName.text=PhotoRec Carver
|
||||||
moduleDescription.text=Runs PhotoRec carver against unallocated space in the data source.
|
moduleDescription.text=Runs PhotoRec carver against unallocated space in the data source.
|
||||||
|
# {0} - extensions
|
||||||
|
PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description=The following extensions are invalid: {0}
|
||||||
|
PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description=No extensions provided for PhotoRec to carve.
|
||||||
PhotoRecIngestModule.nonHostnameUNCPathUsed=PhotoRec cannot operate with a UNC path containing IP addresses.
|
PhotoRecIngestModule.nonHostnameUNCPathUsed=PhotoRec cannot operate with a UNC path containing IP addresses.
|
||||||
PhotoRecIngestModule.PermissionsNotSufficient=Insufficient permissions accessing
|
PhotoRecIngestModule.PermissionsNotSufficient=Insufficient permissions accessing
|
||||||
PhotoRecIngestModule.PermissionsNotSufficientSeeReference=See 'Shared Drive Authentication' in Autopsy help.
|
PhotoRecIngestModule.PermissionsNotSufficientSeeReference=See 'Shared Drive Authentication' in Autopsy help.
|
||||||
@ -26,5 +29,12 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
|
|||||||
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
||||||
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
||||||
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
|
||||||
|
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=
|
||||||
|
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.
|
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.
|
unsupportedOS.message=PhotoRec module is supported on Windows platforms only.
|
||||||
|
@ -29,6 +29,7 @@ import java.nio.file.Paths;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -36,6 +37,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
@ -79,7 +81,11 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||||
|
|
||||||
static final boolean DEFAULT_CONFIG_KEEP_CORRUPTED_FILES = false;
|
static final boolean DEFAULT_CONFIG_KEEP_CORRUPTED_FILES = false;
|
||||||
|
static final PhotoRecCarverIngestJobSettings.ExtensionFilterOption DEFAULT_CONFIG_EXTENSION_FILTER =
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER;
|
||||||
|
|
||||||
|
static final boolean DEFAULT_CONFIG_INCLUDE_ELSE_EXCLUDE = false;
|
||||||
|
|
||||||
private static final String PHOTOREC_DIRECTORY = "photorec_exec"; //NON-NLS
|
private static final String PHOTOREC_DIRECTORY = "photorec_exec"; //NON-NLS
|
||||||
private static final String PHOTOREC_SUBDIRECTORY = "bin"; //NON-NLS
|
private static final String PHOTOREC_SUBDIRECTORY = "bin"; //NON-NLS
|
||||||
private static final String PHOTOREC_EXECUTABLE = "photorec_win.exe"; //NON-NLS
|
private static final String PHOTOREC_EXECUTABLE = "photorec_win.exe"; //NON-NLS
|
||||||
@ -99,23 +105,70 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
private File executableFile;
|
private File executableFile;
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities();
|
private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities();
|
||||||
|
private final PhotoRecCarverIngestJobSettings settings;
|
||||||
|
private String optionsString;
|
||||||
private long jobId;
|
private long jobId;
|
||||||
|
|
||||||
private final boolean keepCorruptedFiles;
|
|
||||||
|
|
||||||
private static class IngestJobTotals {
|
private static class IngestJobTotals {
|
||||||
|
|
||||||
private final AtomicLong totalItemsRecovered = new AtomicLong(0);
|
private final AtomicLong totalItemsRecovered = new AtomicLong(0);
|
||||||
private final AtomicLong totalItemsWithErrors = new AtomicLong(0);
|
private final AtomicLong totalItemsWithErrors = new AtomicLong(0);
|
||||||
private final AtomicLong totalWritetime = new AtomicLong(0);
|
private final AtomicLong totalWritetime = new AtomicLong(0);
|
||||||
private final AtomicLong totalParsetime = new AtomicLong(0);
|
private final AtomicLong totalParsetime = new AtomicLong(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a PhotoRec Carver ingest module instance.
|
* Create a PhotoRec Carver ingest module instance.
|
||||||
*
|
*
|
||||||
* @param settings Ingest job settings used to configure the module.
|
* @param settings Ingest job settings used to configure the module.
|
||||||
*/
|
*/
|
||||||
PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) {
|
PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) {
|
||||||
keepCorruptedFiles = settings.isKeepCorruptedFiles();
|
this.settings = 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<String> toRet = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (settings.isKeepCorruptedFiles()) {
|
||||||
|
toRet.addAll(Arrays.asList("options", "keep_corrupted_file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.getExtensionFilterOption() !=
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER) {
|
||||||
|
|
||||||
|
// 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.getExtensionFilterOption() ==
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE
|
||||||
|
? disable : enable;
|
||||||
|
|
||||||
|
toRet.addAll(Arrays.asList("everything", everythingEnable));
|
||||||
|
|
||||||
|
final String itemEnable = settings.getExtensionFilterOption() ==
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE
|
||||||
|
? enable : disable;
|
||||||
|
|
||||||
|
settings.getExtensions().forEach((extension) -> {
|
||||||
|
toRet.addAll(Arrays.asList(extension, itemEnable));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toRet.add("search");
|
||||||
|
return String.join(",", toRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) {
|
private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) {
|
||||||
@ -136,7 +189,34 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"# {0} - extensions",
|
||||||
|
"PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description=The following extensions are invalid: {0}",
|
||||||
|
"PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description=No extensions provided for PhotoRec to carve."
|
||||||
|
})
|
||||||
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
|
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
|
||||||
|
// validate settings
|
||||||
|
if (this.settings.getExtensionFilterOption() != PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER) {
|
||||||
|
if (this.settings.getExtensions().isEmpty() &&
|
||||||
|
this.settings.getExtensionFilterOption() == PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE) {
|
||||||
|
|
||||||
|
throw new IngestModule.IngestModuleException(
|
||||||
|
Bundle.PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> invalidExtensions = this.settings.getExtensions().stream()
|
||||||
|
.filter((ext) -> !PhotoRecCarverFileOptExtensions.isValidExtension(ext))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (!invalidExtensions.isEmpty()) {
|
||||||
|
throw new IngestModule.IngestModuleException(
|
||||||
|
Bundle.PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description(
|
||||||
|
String.join(",", invalidExtensions)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.optionsString = getPhotorecOptions(this.settings);
|
||||||
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.services = IngestServices.getInstance();
|
this.services = IngestServices.getInstance();
|
||||||
this.jobId = this.context.getJobId();
|
this.jobId = this.context.getJobId();
|
||||||
@ -152,7 +232,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
this.rootOutputDirPath = createModuleOutputDirectoryForCase();
|
this.rootOutputDirPath = createModuleOutputDirectoryForCase();
|
||||||
|
|
||||||
//Set photorec executable directory based on operating system.
|
//Set photorec executable directory based on operating system.
|
||||||
executableFile = locateExecutable();
|
executableFile = locateExecutable();
|
||||||
|
|
||||||
if (PhotoRecCarverFileIngestModule.refCounter.incrementAndGet(this.jobId) == 1) {
|
if (PhotoRecCarverFileIngestModule.refCounter.incrementAndGet(this.jobId) == 1) {
|
||||||
try {
|
try {
|
||||||
@ -242,12 +322,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE,
|
outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE,
|
||||||
"/cmd", // NON-NLS
|
"/cmd", // NON-NLS
|
||||||
tempFilePath.toFile().toString());
|
tempFilePath.toFile().toString());
|
||||||
if (keepCorruptedFiles) {
|
|
||||||
processAndSettings.command().add("options,keep_corrupted_file,search"); // NON-NLS
|
processAndSettings.command().add(this.optionsString);
|
||||||
} else {
|
|
||||||
processAndSettings.command().add("search"); // NON-NLS
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add environment variable to force PhotoRec to run with the same permissions Autopsy uses
|
// Add environment variable to force PhotoRec to run with the same permissions Autopsy uses
|
||||||
processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
|
processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
|
||||||
processAndSettings.redirectErrorStream(true);
|
processAndSettings.redirectErrorStream(true);
|
||||||
@ -455,7 +532,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds and returns the path to the executable, if able.
|
* Finds and returns the path to the executable, if able.
|
||||||
*
|
*
|
||||||
@ -477,9 +553,9 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
File usrLocalBin = new File("/usr/local/bin/photorec");
|
File usrLocalBin = new File("/usr/local/bin/photorec");
|
||||||
if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
|
if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
|
||||||
photorec_linux_directory = "/usr/bin";
|
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";
|
photorec_linux_directory = "/usr/local/bin";
|
||||||
}else{
|
} else {
|
||||||
throw new IngestModule.IngestModuleException("Photorec not found");
|
throw new IngestModule.IngestModuleException("Photorec not found");
|
||||||
}
|
}
|
||||||
execName = Paths.get(photorec_linux_directory, PHOTOREC_LINUX_EXECUTABLE);
|
execName = Paths.get(photorec_linux_directory, PHOTOREC_LINUX_EXECUTABLE);
|
||||||
@ -489,8 +565,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
if (null == exeFile) {
|
if (null == exeFile) {
|
||||||
throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message());
|
throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!exeFile.canExecute()) {
|
if (!exeFile.canExecute()) {
|
||||||
throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message());
|
throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message());
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,384 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.photoreccarver;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies what extensions can be used for the "fileopt" option of photorec,
|
||||||
|
* which allows certain extensions to be included or excluded.
|
||||||
|
*/
|
||||||
|
final class PhotoRecCarverFileOptExtensions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the extension provided in the string can be used with
|
||||||
|
* photorec.
|
||||||
|
*
|
||||||
|
* @param extension The extension (i.e. 'exe').
|
||||||
|
*
|
||||||
|
* @return True if the extension can be used with photorec.
|
||||||
|
*/
|
||||||
|
static boolean isValidExtension(String extension) {
|
||||||
|
return KNOWN_EXTENSIONS.contains(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This was generated by photorec. It can be generated by 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 working directory with all the extensions.
|
||||||
|
private static final Set<String> KNOWN_EXTENSIONS = new HashSet<String>(Arrays.asList(
|
||||||
|
"1cd",
|
||||||
|
"3dm",
|
||||||
|
"7z",
|
||||||
|
"DB",
|
||||||
|
"a",
|
||||||
|
"abr",
|
||||||
|
"acb",
|
||||||
|
"accdb",
|
||||||
|
"ace",
|
||||||
|
"ab",
|
||||||
|
"ado",
|
||||||
|
"afdesign",
|
||||||
|
"ahn",
|
||||||
|
"aif",
|
||||||
|
"all",
|
||||||
|
"als",
|
||||||
|
"amd",
|
||||||
|
"amr",
|
||||||
|
"apa",
|
||||||
|
"ape",
|
||||||
|
"apple",
|
||||||
|
"ari",
|
||||||
|
"arj",
|
||||||
|
"asf",
|
||||||
|
"asl",
|
||||||
|
"asm",
|
||||||
|
"atd",
|
||||||
|
"au",
|
||||||
|
"axp",
|
||||||
|
"axx",
|
||||||
|
"bac",
|
||||||
|
"bdm",
|
||||||
|
"db",
|
||||||
|
"bim",
|
||||||
|
"bin",
|
||||||
|
"binvox",
|
||||||
|
"bkf",
|
||||||
|
"blend",
|
||||||
|
"bmp",
|
||||||
|
"bpg",
|
||||||
|
"bvr",
|
||||||
|
"bz2",
|
||||||
|
"c4d",
|
||||||
|
"cab",
|
||||||
|
"caf",
|
||||||
|
"cam",
|
||||||
|
"catdrawing",
|
||||||
|
"cdt",
|
||||||
|
"che",
|
||||||
|
"chm",
|
||||||
|
"class",
|
||||||
|
"comicdoc",
|
||||||
|
"cp_",
|
||||||
|
"cow",
|
||||||
|
"cpi",
|
||||||
|
"crw",
|
||||||
|
"csh",
|
||||||
|
"ctg",
|
||||||
|
"cwk",
|
||||||
|
"d2s",
|
||||||
|
"dad",
|
||||||
|
"dar",
|
||||||
|
"dat",
|
||||||
|
"dbf",
|
||||||
|
"dbn",
|
||||||
|
"dcm",
|
||||||
|
"ddf",
|
||||||
|
"dex",
|
||||||
|
"diskimage",
|
||||||
|
"fat",
|
||||||
|
"djv",
|
||||||
|
"dmp",
|
||||||
|
"drw",
|
||||||
|
"doc",
|
||||||
|
"dpx",
|
||||||
|
"ds2",
|
||||||
|
"DS_Store",
|
||||||
|
"dsc",
|
||||||
|
"dss",
|
||||||
|
"dst",
|
||||||
|
"dta",
|
||||||
|
"dump",
|
||||||
|
"dv",
|
||||||
|
"dvi",
|
||||||
|
"dvr",
|
||||||
|
"dwg",
|
||||||
|
"dxf",
|
||||||
|
"e01",
|
||||||
|
"eCryptfs",
|
||||||
|
"edb",
|
||||||
|
"elf",
|
||||||
|
"emf",
|
||||||
|
"ess",
|
||||||
|
"evt",
|
||||||
|
"evtx",
|
||||||
|
"exe",
|
||||||
|
"exs",
|
||||||
|
"ext",
|
||||||
|
"ext",
|
||||||
|
"fat",
|
||||||
|
"fbf",
|
||||||
|
"fbk",
|
||||||
|
"fcp",
|
||||||
|
"fcs",
|
||||||
|
"fdb",
|
||||||
|
"fds",
|
||||||
|
"fh10",
|
||||||
|
"fh5",
|
||||||
|
"sparseimage",
|
||||||
|
"fits",
|
||||||
|
"fit",
|
||||||
|
"flac",
|
||||||
|
"flp",
|
||||||
|
"flv",
|
||||||
|
"fm",
|
||||||
|
"fob",
|
||||||
|
"fos",
|
||||||
|
"fp5",
|
||||||
|
"fp7",
|
||||||
|
"freeway",
|
||||||
|
"frm",
|
||||||
|
"fs",
|
||||||
|
"fwd",
|
||||||
|
"gam",
|
||||||
|
"gct",
|
||||||
|
"gho",
|
||||||
|
"gi",
|
||||||
|
"gif",
|
||||||
|
"gm*",
|
||||||
|
"gp2",
|
||||||
|
"gp5",
|
||||||
|
"gpg",
|
||||||
|
"gpx",
|
||||||
|
"gsm",
|
||||||
|
"gz",
|
||||||
|
"hdf",
|
||||||
|
"hdr",
|
||||||
|
"hds",
|
||||||
|
"hfsp",
|
||||||
|
"hm",
|
||||||
|
"hr9",
|
||||||
|
"http",
|
||||||
|
"ibd",
|
||||||
|
"icc",
|
||||||
|
"icns",
|
||||||
|
"ico",
|
||||||
|
"idx",
|
||||||
|
"ifo",
|
||||||
|
"imb",
|
||||||
|
"indd",
|
||||||
|
"info",
|
||||||
|
"iso",
|
||||||
|
"it",
|
||||||
|
"itu",
|
||||||
|
"jks",
|
||||||
|
"jpg",
|
||||||
|
"jsonlz4",
|
||||||
|
"kdb",
|
||||||
|
"kdbx",
|
||||||
|
"key",
|
||||||
|
"ldf",
|
||||||
|
"lit",
|
||||||
|
"logic",
|
||||||
|
"lnk",
|
||||||
|
"lso",
|
||||||
|
"luks",
|
||||||
|
"lxo",
|
||||||
|
"lzh",
|
||||||
|
"lzo",
|
||||||
|
"m2ts",
|
||||||
|
"mat",
|
||||||
|
"max",
|
||||||
|
"mb",
|
||||||
|
"mcd",
|
||||||
|
"mdb",
|
||||||
|
"mdf",
|
||||||
|
"mfa",
|
||||||
|
"mfg",
|
||||||
|
"mft",
|
||||||
|
"mid",
|
||||||
|
"mig",
|
||||||
|
"mk5",
|
||||||
|
"mkv",
|
||||||
|
"mlv",
|
||||||
|
"mobi",
|
||||||
|
"mov/mdat",
|
||||||
|
"mov",
|
||||||
|
"mp3",
|
||||||
|
"mpg",
|
||||||
|
"mpl",
|
||||||
|
"mrw",
|
||||||
|
"msa",
|
||||||
|
"mus",
|
||||||
|
"myo",
|
||||||
|
"MYI",
|
||||||
|
"mxf",
|
||||||
|
"nd2",
|
||||||
|
"nds",
|
||||||
|
"nes",
|
||||||
|
"njx",
|
||||||
|
"nk2",
|
||||||
|
"nsf",
|
||||||
|
"oci",
|
||||||
|
"ogg",
|
||||||
|
"one",
|
||||||
|
"orf",
|
||||||
|
"paf",
|
||||||
|
"pap",
|
||||||
|
"par2",
|
||||||
|
"pcap",
|
||||||
|
"pcb",
|
||||||
|
"pct",
|
||||||
|
"pcx",
|
||||||
|
"pdb",
|
||||||
|
"pdf",
|
||||||
|
"pds",
|
||||||
|
"pf",
|
||||||
|
"pfx",
|
||||||
|
"dump",
|
||||||
|
"plist",
|
||||||
|
"plr",
|
||||||
|
"plt",
|
||||||
|
"png",
|
||||||
|
"pnm",
|
||||||
|
"prc",
|
||||||
|
"prd",
|
||||||
|
"prt",
|
||||||
|
"ps",
|
||||||
|
"psb",
|
||||||
|
"psd",
|
||||||
|
"psf",
|
||||||
|
"psp",
|
||||||
|
"pst",
|
||||||
|
"ptb",
|
||||||
|
"ptf",
|
||||||
|
"pyc",
|
||||||
|
"pzf",
|
||||||
|
"pzh",
|
||||||
|
"qbb",
|
||||||
|
"qdf",
|
||||||
|
"qkt",
|
||||||
|
"qxd",
|
||||||
|
"r3d",
|
||||||
|
"ra",
|
||||||
|
"raf",
|
||||||
|
"rar",
|
||||||
|
"raw",
|
||||||
|
"rdc",
|
||||||
|
"reg",
|
||||||
|
"res",
|
||||||
|
"rfp",
|
||||||
|
"riff",
|
||||||
|
"rlv",
|
||||||
|
"rm",
|
||||||
|
"rns",
|
||||||
|
"rpm",
|
||||||
|
"rw2",
|
||||||
|
"rx2",
|
||||||
|
"save",
|
||||||
|
"ses",
|
||||||
|
"sgcta",
|
||||||
|
"shn",
|
||||||
|
"sib",
|
||||||
|
"sit",
|
||||||
|
"skd",
|
||||||
|
"skp",
|
||||||
|
"snag",
|
||||||
|
"snz",
|
||||||
|
"sp3",
|
||||||
|
"spe",
|
||||||
|
"spf",
|
||||||
|
"sav",
|
||||||
|
"sqlite",
|
||||||
|
"sqm",
|
||||||
|
"steuer2014",
|
||||||
|
"stl",
|
||||||
|
"studio",
|
||||||
|
"sit",
|
||||||
|
"swf",
|
||||||
|
"tar",
|
||||||
|
"tax",
|
||||||
|
"tg",
|
||||||
|
"tib",
|
||||||
|
"tif",
|
||||||
|
"TiVo",
|
||||||
|
"torrent",
|
||||||
|
"tph",
|
||||||
|
"tpl",
|
||||||
|
"ts",
|
||||||
|
"ttf",
|
||||||
|
"tx?",
|
||||||
|
"txt",
|
||||||
|
"tz",
|
||||||
|
"v2i",
|
||||||
|
"vault",
|
||||||
|
"vdj",
|
||||||
|
"vfb",
|
||||||
|
"vdi",
|
||||||
|
"veg",
|
||||||
|
"vib",
|
||||||
|
"vmdk",
|
||||||
|
"vmg",
|
||||||
|
"wallet",
|
||||||
|
"wdp",
|
||||||
|
"wee",
|
||||||
|
"wim",
|
||||||
|
"win",
|
||||||
|
"wks",
|
||||||
|
"wld",
|
||||||
|
"wmf",
|
||||||
|
"wnk",
|
||||||
|
"woff",
|
||||||
|
"wpb",
|
||||||
|
"wpd",
|
||||||
|
"wtv",
|
||||||
|
"wv",
|
||||||
|
"x3f",
|
||||||
|
"x3i",
|
||||||
|
"x4a",
|
||||||
|
"xar",
|
||||||
|
"xcf",
|
||||||
|
"xfi",
|
||||||
|
"xfs",
|
||||||
|
"xm",
|
||||||
|
"xml",
|
||||||
|
"xsv",
|
||||||
|
"xpt",
|
||||||
|
"xv",
|
||||||
|
"xz",
|
||||||
|
"z2d",
|
||||||
|
"zcode",
|
||||||
|
"zip",
|
||||||
|
"zpr"));
|
||||||
|
|
||||||
|
private PhotoRecCarverFileOptExtensions() {
|
||||||
|
}
|
||||||
|
}
|
@ -18,53 +18,132 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.photoreccarver;
|
package org.sleuthkit.autopsy.modules.photoreccarver;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ingest job settings for the PhotoRec Carver module.
|
* Ingest job settings for the PhotoRec Carver module.
|
||||||
*/
|
*/
|
||||||
final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSettings {
|
final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSettings {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What kind of filtering should occur for the extension list.
|
||||||
|
*/
|
||||||
|
enum ExtensionFilterOption {
|
||||||
|
/**
|
||||||
|
* The file extensions should be included (and others should be
|
||||||
|
* filtered).
|
||||||
|
*/
|
||||||
|
INCLUDE,
|
||||||
|
/**
|
||||||
|
* The extensions should be excluded from the results list.
|
||||||
|
*/
|
||||||
|
EXCLUDE,
|
||||||
|
/**
|
||||||
|
* No extension filtering should take place.
|
||||||
|
*/
|
||||||
|
NO_FILTER
|
||||||
|
};
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private boolean keepCorruptedFiles;
|
private boolean keepCorruptedFiles;
|
||||||
|
private List<String> extensions;
|
||||||
|
private ExtensionFilterOption extensionFilterOption;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the ingest job settings with default values.
|
* Instantiate the ingest job settings with default values.
|
||||||
*/
|
*/
|
||||||
PhotoRecCarverIngestJobSettings() {
|
PhotoRecCarverIngestJobSettings() {
|
||||||
this.keepCorruptedFiles = PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES;
|
this(PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES,
|
||||||
|
PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_EXTENSION_FILTER,
|
||||||
|
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
|
||||||
|
* @param extensionFilterOption How the includeExcludeExtensions should
|
||||||
|
* be filtered.
|
||||||
|
* @param includeExcludeExtensions The extensions to include or exclude
|
||||||
|
* (i.e. jpg, gif)
|
||||||
*/
|
*/
|
||||||
PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles) {
|
PhotoRecCarverIngestJobSettings(boolean keepCorruptedFiles, ExtensionFilterOption extensionFilterOption, List<String> includeExcludeExtensions) {
|
||||||
this.keepCorruptedFiles = keepCorruptedFiles;
|
this.keepCorruptedFiles = keepCorruptedFiles;
|
||||||
|
setExtensionFilterOption(extensionFilterOption);
|
||||||
|
setExtensions(includeExcludeExtensions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getVersionNumber() {
|
public long getVersionNumber() {
|
||||||
return serialVersionUID;
|
return serialVersionUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are corrupted files being kept?
|
* Are corrupted files being kept?
|
||||||
*
|
*
|
||||||
* @return True if keeping corrupted files; otherwise false.
|
* @return True if keeping corrupted files; otherwise false.
|
||||||
*/
|
*/
|
||||||
boolean isKeepCorruptedFiles() {
|
boolean isKeepCorruptedFiles() {
|
||||||
return keepCorruptedFiles;
|
return keepCorruptedFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep or disgard corrupted files.
|
* Keep or disgard corrupted files.
|
||||||
*
|
*
|
||||||
* @param keepCorruptedFiles Are corrupted files being kept?
|
* @param keepCorruptedFiles Are corrupted files being kept?
|
||||||
*/
|
*/
|
||||||
void setKeepCorruptedFiles(boolean keepCorruptedFiles) {
|
void setKeepCorruptedFiles(boolean keepCorruptedFiles) {
|
||||||
this.keepCorruptedFiles = keepCorruptedFiles;
|
this.keepCorruptedFiles = keepCorruptedFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets extension names (i.e. jpg, exe) to include or exclude from photorec
|
||||||
|
* carving.
|
||||||
|
*
|
||||||
|
* @return The extension names.
|
||||||
|
*/
|
||||||
|
List<String> getExtensions() {
|
||||||
|
return extensions == null
|
||||||
|
? Collections.emptyList()
|
||||||
|
: Collections.unmodifiableList(extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets extension names (i.e. jpg, exe) to include or exclude from photorec
|
||||||
|
* carving.
|
||||||
|
*
|
||||||
|
* @param includeExcludeExtensions The extension names.
|
||||||
|
*/
|
||||||
|
void setExtensions(List<String> includeExcludeExtensions) {
|
||||||
|
this.extensions = new ArrayList<>();
|
||||||
|
if (includeExcludeExtensions != null) {
|
||||||
|
this.extensions.addAll(includeExcludeExtensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How extension filtering should be handled.
|
||||||
|
* @return How extension filtering should be handled.
|
||||||
|
*/
|
||||||
|
ExtensionFilterOption getExtensionFilterOption() {
|
||||||
|
return (this.extensionFilterOption == null) ?
|
||||||
|
ExtensionFilterOption.NO_FILTER :
|
||||||
|
extensionFilterOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets how extension filtering should be handled.
|
||||||
|
* @param extensionFilterOption How extension filtering should be handled.
|
||||||
|
*/
|
||||||
|
void setExtensionFilterOption(ExtensionFilterOption extensionFilterOption) {
|
||||||
|
this.extensionFilterOption = (extensionFilterOption == null) ?
|
||||||
|
ExtensionFilterOption.NO_FILTER :
|
||||||
|
extensionFilterOption;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<NonVisualComponents>
|
||||||
|
<Component class="javax.swing.ButtonGroup" name="includeExcludeButtonGroup">
|
||||||
|
</Component>
|
||||||
|
</NonVisualComponents>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
@ -16,16 +20,30 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="keepCorruptedFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="detectionSettingsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="keepCorruptedFilesCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="includeExcludeCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="includeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="excludeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<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="extensionListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="fullListOfTypesHyperlink" alignment="0" min="-2" pref="247" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="detectionSettingsLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace pref="159" max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -34,9 +52,25 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="detectionSettingsLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="detectionSettingsLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="2" max="2" attributes="0"/>
|
||||||
<Component id="keepCorruptedFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
<Component id="keepCorruptedFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="145" max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="includeExcludeCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="includeRadioButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="excludeRadioButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
|
||||||
|
<Component id="extensionListLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="extensionListTextfield" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="exampleLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="fullListOfTypesLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="fullListOfTypesHyperlink" min="-2" pref="36" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -60,6 +94,82 @@
|
|||||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties" key="PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties" key="PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="includeExcludeCheckbox">
|
||||||
|
<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.includeExcludeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="includeExcludeCheckboxActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="excludeRadioButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="includeExcludeButtonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<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.excludeRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="exampleLabel">
|
||||||
|
<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.exampleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="fullListOfTypesLabel">
|
||||||
|
<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.fullListOfTypesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="extensionListLabel">
|
||||||
|
<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.extensionListLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="extensionListTextfield">
|
||||||
|
<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.extensionListTextfield.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="includeRadioButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="includeExcludeButtonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
|
<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.includeRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextArea" name="fullListOfTypesHyperlink">
|
||||||
|
<Properties>
|
||||||
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
|
<Property name="columns" type="int" value="20"/>
|
||||||
|
<Property name="lineWrap" type="boolean" value="true"/>
|
||||||
|
<Property name="rows" type="int" value="5"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="PHOTOREC_TYPES_URL" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
|
<Property name="opaque" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018 Basis Technology Corp.
|
* Copyright 2018-2020 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,8 +18,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.photoreccarver;
|
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.IngestModuleIngestJobSettings;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ingest job settings panel for the Encryption Detection module.
|
* Ingest job settings panel for the Encryption Detection module.
|
||||||
@ -27,6 +42,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
|||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel {
|
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 = "http://sleuthkit.org/autopsy/docs/user-docs/latest/photorec_carver_page.html";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the ingest job settings panel.
|
* Instantiate the ingest job settings panel.
|
||||||
*
|
*
|
||||||
@ -43,13 +62,100 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
* @param settings The ingest job settings.
|
* @param settings The ingest job settings.
|
||||||
*/
|
*/
|
||||||
private void customizeComponents(PhotoRecCarverIngestJobSettings settings) {
|
private void customizeComponents(PhotoRecCarverIngestJobSettings settings) {
|
||||||
|
includeExcludeCheckbox.setSelected(settings.getExtensionFilterOption() != PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER);
|
||||||
|
extensionListTextfield.setText(String.join(EXTENSION_LIST_SEPARATOR, settings.getExtensions()));
|
||||||
|
includeRadioButton.setSelected(settings.getExtensionFilterOption() == PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE);
|
||||||
|
excludeRadioButton.setSelected(settings.getExtensionFilterOption() == PhotoRecCarverIngestJobSettings.ExtensionFilterOption.EXCLUDE);
|
||||||
keepCorruptedFilesCheckbox.setSelected(settings.isKeepCorruptedFiles());
|
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 hyperlink: " + 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
|
@Override
|
||||||
public IngestModuleIngestJobSettings getSettings() {
|
public IngestModuleIngestJobSettings getSettings() {
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption filterOption =
|
||||||
|
PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER;
|
||||||
|
|
||||||
|
if (includeExcludeCheckbox.isSelected()) {
|
||||||
|
if (includeRadioButton.isSelected()) {
|
||||||
|
filterOption = PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE;
|
||||||
|
} else {
|
||||||
|
filterOption = PhotoRecCarverIngestJobSettings.ExtensionFilterOption.EXCLUDE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return new PhotoRecCarverIngestJobSettings(
|
return new PhotoRecCarverIngestJobSettings(
|
||||||
keepCorruptedFilesCheckbox.isSelected());
|
keepCorruptedFilesCheckbox.isSelected(),
|
||||||
|
filterOption,
|
||||||
|
getExtensions(extensionListTextfield.getText())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines a list of extensions to pass as parameters to photorec based
|
||||||
|
* on the specified input.
|
||||||
|
*
|
||||||
|
* @param combinedList The comma-separated list.
|
||||||
|
*
|
||||||
|
* @return The list of strings to use with photorec.
|
||||||
|
*/
|
||||||
|
private List<String> getExtensions(String combinedList) {
|
||||||
|
if (StringUtils.isBlank(combinedList)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.of(combinedList.split(EXTENSION_LIST_SEPARATOR))
|
||||||
|
.map(ext -> ext.trim())
|
||||||
|
.filter(ext -> StringUtils.isNotBlank(ext))
|
||||||
|
.sorted((a, b) -> a.toLowerCase().compareTo(b.toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,40 +167,120 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
|
includeExcludeButtonGroup = new javax.swing.ButtonGroup();
|
||||||
keepCorruptedFilesCheckbox = new javax.swing.JCheckBox();
|
keepCorruptedFilesCheckbox = new javax.swing.JCheckBox();
|
||||||
detectionSettingsLabel = new javax.swing.JLabel();
|
javax.swing.JLabel detectionSettingsLabel = new javax.swing.JLabel();
|
||||||
|
includeExcludeCheckbox = new javax.swing.JCheckBox();
|
||||||
|
excludeRadioButton = new javax.swing.JRadioButton();
|
||||||
|
exampleLabel = new javax.swing.JLabel();
|
||||||
|
fullListOfTypesLabel = new javax.swing.JLabel();
|
||||||
|
extensionListLabel = new javax.swing.JLabel();
|
||||||
|
extensionListTextfield = new javax.swing.JTextField();
|
||||||
|
includeRadioButton = new javax.swing.JRadioButton();
|
||||||
|
fullListOfTypesHyperlink = new javax.swing.JTextArea();
|
||||||
|
|
||||||
|
setPreferredSize(null);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(keepCorruptedFilesCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text")); // NOI18N
|
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));
|
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(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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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(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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
fullListOfTypesHyperlink.setEditable(false);
|
||||||
|
fullListOfTypesHyperlink.setColumns(20);
|
||||||
|
fullListOfTypesHyperlink.setLineWrap(true);
|
||||||
|
fullListOfTypesHyperlink.setRows(5);
|
||||||
|
fullListOfTypesHyperlink.setText(PHOTOREC_TYPES_URL);
|
||||||
|
fullListOfTypesHyperlink.setFocusable(false);
|
||||||
|
fullListOfTypesHyperlink.setOpaque(false);
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(10, 10, 10)
|
.addContainerGap()
|
||||||
.addComponent(keepCorruptedFilesCheckbox))
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(detectionSettingsLabel))
|
.addComponent(detectionSettingsLabel)
|
||||||
.addContainerGap(159, Short.MAX_VALUE))
|
.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, 247, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(detectionSettingsLabel)
|
.addComponent(detectionSettingsLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addGap(0, 2, 2)
|
||||||
.addComponent(keepCorruptedFilesCheckbox)
|
.addComponent(keepCorruptedFilesCheckbox)
|
||||||
.addContainerGap(145, Short.MAX_VALUE))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(includeExcludeCheckbox)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.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, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//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
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JLabel detectionSettingsLabel;
|
private javax.swing.JLabel exampleLabel;
|
||||||
|
private javax.swing.JRadioButton excludeRadioButton;
|
||||||
|
private javax.swing.JLabel extensionListLabel;
|
||||||
|
private javax.swing.JTextField extensionListTextfield;
|
||||||
|
private javax.swing.JTextArea fullListOfTypesHyperlink;
|
||||||
|
private javax.swing.JLabel fullListOfTypesLabel;
|
||||||
|
private javax.swing.ButtonGroup includeExcludeButtonGroup;
|
||||||
|
private javax.swing.JCheckBox includeExcludeCheckbox;
|
||||||
|
private javax.swing.JRadioButton includeRadioButton;
|
||||||
private javax.swing.JCheckBox keepCorruptedFilesCheckbox;
|
private javax.swing.JCheckBox keepCorruptedFilesCheckbox;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
|
|||||||
KeywordSearchResultFactory.query.exception.msg=Could not perform the query
|
KeywordSearchResultFactory.query.exception.msg=Could not perform the query
|
||||||
OpenIDE-Module-Display-Category=Ingest Module
|
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
|
OpenIDE-Module-Name=KeywordSearch
|
||||||
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
|
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
|
||||||
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
|
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
|
||||||
|
@ -18,15 +18,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
@ -81,6 +84,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
column.setPreferredWidth(((int) (width * 0.07)));
|
column.setPreferredWidth(((int) (width * 0.07)));
|
||||||
} else {
|
} else {
|
||||||
|
column.setCellRenderer(new KeywordTableCellRenderer());
|
||||||
column.setPreferredWidth(((int) (width * 0.92)));
|
column.setPreferredWidth(((int) (width * 0.92)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,6 +183,25 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
|||||||
displayEncodings();
|
displayEncodings();
|
||||||
tableModel.fireTableDataChanged();
|
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 {
|
private class KeywordListsTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
@ -131,7 +131,8 @@ def get_prop_entries(rows: List[List[str]],
|
|||||||
should_delete_converter: Callable[[List[str]], bool] = None,
|
should_delete_converter: Callable[[List[str]], bool] = None,
|
||||||
path_converter: Callable[[str], str] = None) -> Iterator[PropEntry]:
|
path_converter: Callable[[str], str] = None) -> Iterator[PropEntry]:
|
||||||
|
|
||||||
"""Parses PropEntry objects from rows of values in a csv.
|
"""Parses PropEntry objects from rows of values in a csv. Any items that have an empty string value will be
|
||||||
|
ignored.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
rows (List[List[str]]): The csv file rows to parse.
|
rows (List[List[str]]): The csv file rows to parse.
|
||||||
@ -146,9 +147,11 @@ def get_prop_entries(rows: List[List[str]],
|
|||||||
Returns:
|
Returns:
|
||||||
List[PropEntry]: The generated prop entry objects.
|
List[PropEntry]: The generated prop entry objects.
|
||||||
"""
|
"""
|
||||||
return map(lambda row: get_prop_entry(
|
propentry_iter = map(lambda row: get_prop_entry(row, path_idx, key_idx, value_idx, should_delete_converter,
|
||||||
row, path_idx, key_idx, value_idx, should_delete_converter, path_converter),
|
path_converter), rows)
|
||||||
rows)
|
|
||||||
|
# filter rows that have no value
|
||||||
|
return filter(lambda entry: entry and entry.value.strip(), propentry_iter)
|
||||||
|
|
||||||
|
|
||||||
def get_should_deleted(row_items: List[str], requested_idx: int) -> bool:
|
def get_should_deleted(row_items: List[str], requested_idx: int) -> bool:
|
||||||
|
4
thirdparty/photorec_exec/README.txt
vendored
4
thirdparty/photorec_exec/README.txt
vendored
@ -1,4 +1,6 @@
|
|||||||
The 'bin' folder is the version used when running the PhotoRec ingest module. It is also the 32-bit version.
|
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 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.
|
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.
|
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.
|
@ -21,13 +21,11 @@ package org.sleuthkit.autopsy.thunderbirdparser;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
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.Body;
|
||||||
import org.apache.james.mime4j.dom.Entity;
|
import org.apache.james.mime4j.dom.Entity;
|
||||||
import org.apache.james.mime4j.dom.Message;
|
import org.apache.james.mime4j.dom.Message;
|
||||||
@ -227,15 +225,15 @@ class MimeJ4MessageParser {
|
|||||||
} else if (e.getDispositionType() != null
|
} else if (e.getDispositionType() != null
|
||||||
&& e.getDispositionType().equals(ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT)) {
|
&& e.getDispositionType().equals(ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT)) {
|
||||||
handleAttachment(email, e, fileID, index);
|
handleAttachment(email, e, fileID, index);
|
||||||
} else if (e.getMimeType().equals(HTML_TYPE)
|
} else if ((e.getMimeType().equals(HTML_TYPE) && (email.getHtmlBody() == null || email.getHtmlBody().isEmpty()))
|
||||||
|| e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN)) {
|
|| (e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN) && (email.getTextBody() == null || email.getTextBody().isEmpty()))) {
|
||||||
handleTextBody(email, (TextBody) e.getBody(), e.getMimeType(), e.getHeader().getFields());
|
handleTextBody(email, (TextBody) e.getBody(), e.getMimeType(), e.getHeader().getFields());
|
||||||
} else {
|
} else {
|
||||||
// Ignore other types.
|
handleAttachment(email, e, fileID, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract text out of a body part of the message.
|
* Extract text out of a body part of the message.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user