Merge pull request #6172 from sleuthkit/develop

Merge develop into data_source_summary_result_viewer
This commit is contained in:
Richard Cordovano 2020-08-11 11:20:02 -04:00 committed by GitHub
commit 0da9a4dc09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1036 additions and 73 deletions

View File

@ -18,9 +18,12 @@
*/
package org.sleuthkit.autopsy.communications;
import java.awt.Component;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.TimeZone;
import javax.swing.table.TableCellRenderer;
import org.netbeans.swing.outline.Outline;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
import org.sleuthkit.datamodel.Account;
@ -48,4 +51,28 @@ public final class Utils {
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);
}
}
}

View File

@ -73,5 +73,5 @@ SummaryViewer.referencesLabel.text=Communication References:
SummaryViewer.referencesDataLabel.text=<reference count>
SummaryViewer.contactsLabel.text=Book Entries:
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>

View File

@ -38,6 +38,8 @@ import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
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.Outline;
import org.openide.explorer.ExplorerManager;
@ -50,6 +52,7 @@ import org.openide.nodes.Node.PropertySet;
import org.openide.util.Lookup;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
import org.sleuthkit.autopsy.communications.Utils;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
@ -116,6 +119,13 @@ final class MessageViewer extends JPanel implements RelationshipsViewer {
}
});
rootTablePane.getOutlineView().getOutline().getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
Utils.setColumnWidths(rootTablePane.getOutlineView().getOutline());
}
});
threadMessagesPanel.setChildFactory(threadMessageNodeFactory);
rootTablePane.setTableColumnsWidth(10, 20, 70);

View File

@ -72,7 +72,10 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
*/
@Override
public void cancel() {
getPanel().cancel();
if(changed) {
getPanel().cancel();
changed = false;
}
}
@Override

View File

@ -326,17 +326,19 @@ public class HashDbManager implements PropertyChangeListener {
}
// 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 {
changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName);
} catch (Exception e) {
logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"),
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"),
MessageNotifyUtil.MessageType.ERROR);
// Let any external listeners know that there's a new set
try {
changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName);
} catch (Exception e) {
logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErr"),
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
return db;

View File

@ -18,14 +18,17 @@
*/
package org.sleuthkit.autopsy.modules.hashdatabase;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.apache.commons.lang.StringUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -78,6 +81,7 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
if (i == 0) {
column.setPreferredWidth(((int) (width1 * 0.07)));
} else {
column.setCellRenderer(new HashSetTableCellRenderer());
column.setPreferredWidth(((int) (width1 * 0.92)));
}
}
@ -226,6 +230,24 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
}
}
/**
* 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 long serialVersionUID = 1L;

View File

@ -18,13 +18,16 @@
*/
package org.sleuthkit.autopsy.modules.interestingitems;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.TreeMap;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
@ -110,6 +113,7 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
if (i == 0) {
column.setPreferredWidth(((int) (width * 0.07)));
} else {
column.setCellRenderer(new FileSetsTableCellRenderer());
column.setPreferredWidth(((int) (width * 0.92)));
}
}
@ -159,6 +163,24 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
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
* disable interesting files set definitions for an ingest job.

View File

@ -19,3 +19,10 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=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

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
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.PermissionsNotSufficient=Insufficient permissions accessing
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:
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
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.
unsupportedOS.message=PhotoRec module is supported on Windows platforms only.

View File

@ -29,6 +29,7 @@ import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -36,6 +37,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
@ -79,6 +81,10 @@ import org.sleuthkit.datamodel.TskData;
final class PhotoRecCarverFileIngestModule implements FileIngestModule {
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_SUBDIRECTORY = "bin"; //NON-NLS
@ -99,23 +105,70 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
private File executableFile;
private IngestServices services;
private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities();
private final PhotoRecCarverIngestJobSettings settings;
private String optionsString;
private long jobId;
private final boolean keepCorruptedFiles;
private static class IngestJobTotals {
private final AtomicLong totalItemsRecovered = new AtomicLong(0);
private final AtomicLong totalItemsWithErrors = new AtomicLong(0);
private final AtomicLong totalWritetime = new AtomicLong(0);
private final AtomicLong totalParsetime = new AtomicLong(0);
}
/**
* Create a PhotoRec Carver ingest module instance.
*
* @param settings Ingest job settings used to configure the module.
*/
PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) {
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) {
@ -136,7 +189,34 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
* @inheritDoc
*/
@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 {
// 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.services = IngestServices.getInstance();
this.jobId = this.context.getJobId();
@ -152,7 +232,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
this.rootOutputDirPath = createModuleOutputDirectoryForCase();
//Set photorec executable directory based on operating system.
executableFile = locateExecutable();
executableFile = locateExecutable();
if (PhotoRecCarverFileIngestModule.refCounter.incrementAndGet(this.jobId) == 1) {
try {
@ -242,11 +322,8 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE,
"/cmd", // NON-NLS
tempFilePath.toFile().toString());
if (keepCorruptedFiles) {
processAndSettings.command().add("options,keep_corrupted_file,search"); // NON-NLS
} else {
processAndSettings.command().add("search"); // NON-NLS
}
processAndSettings.command().add(this.optionsString);
// Add environment variable to force PhotoRec to run with the same permissions Autopsy uses
processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
@ -455,7 +532,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
return path;
}
/**
* 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");
if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
photorec_linux_directory = "/usr/bin";
}else if(usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()){
} else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
photorec_linux_directory = "/usr/local/bin";
}else{
} else {
throw new IngestModule.IngestModuleException("Photorec not found");
}
execName = Paths.get(photorec_linux_directory, PHOTOREC_LINUX_EXECUTABLE);
@ -490,7 +566,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message());
}
if (!exeFile.canExecute()) {
throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message());
}

View File

@ -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() {
}
}

View File

@ -18,31 +18,65 @@
*/
package org.sleuthkit.autopsy.modules.photoreccarver;
import java.util.ArrayList;
import java.util.Collections;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import java.util.List;
/**
* Ingest job settings for the PhotoRec Carver module.
*/
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 boolean keepCorruptedFiles;
private List<String> extensions;
private ExtensionFilterOption extensionFilterOption;
/**
* Instantiate the ingest job settings with default values.
*/
PhotoRecCarverIngestJobSettings() {
this.keepCorruptedFiles = PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES;
this(PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_KEEP_CORRUPTED_FILES,
PhotoRecCarverFileIngestModule.DEFAULT_CONFIG_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;
setExtensionFilterOption(extensionFilterOption);
setExtensions(includeExcludeExtensions);
}
@Override
@ -67,4 +101,49 @@ final class PhotoRecCarverIngestJobSettings implements IngestModuleIngestJobSett
void setKeepCorruptedFiles(boolean keepCorruptedFiles) {
this.keepCorruptedFiles = keepCorruptedFiles;
}
/**
* Gets extension names (i.e. jpg, exe) to include or exclude from photorec
* carving.
*
* @return The extension names.
*/
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;
}
}

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<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>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -16,16 +20,30 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Component id="keepCorruptedFilesCheckbox" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace 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>
<Component id="detectionSettingsLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="159" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -34,9 +52,25 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace 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"/>
<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>
</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, &quot;{key}&quot;)"/>
</Property>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Copyright 2018-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,8 +18,23 @@
*/
package org.sleuthkit.autopsy.modules.photoreccarver;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang.StringUtils;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Ingest job settings panel for the Encryption Detection module.
@ -27,6 +42,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel {
private static final Logger logger = Logger.getLogger(PhotoRecCarverIngestJobSettingsPanel.class.getName());
private static final String EXTENSION_LIST_SEPARATOR = ",";
private static final String PHOTOREC_TYPES_URL = "http://sleuthkit.org/autopsy/docs/user-docs/latest/photorec_carver_page.html";
/**
* Instantiate the ingest job settings panel.
*
@ -43,13 +62,100 @@ final class PhotoRecCarverIngestJobSettingsPanel extends IngestModuleIngestJobSe
* @param settings The ingest job 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());
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
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(
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
private void initComponents() {
includeExcludeButtonGroup = new javax.swing.ButtonGroup();
keepCorruptedFilesCheckbox = new javax.swing.JCheckBox();
detectionSettingsLabel = new javax.swing.JLabel();
javax.swing.JLabel detectionSettingsLabel = new javax.swing.JLabel();
includeExcludeCheckbox = new javax.swing.JCheckBox();
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
detectionSettingsLabel.setFont(detectionSettingsLabel.getFont().deriveFont(detectionSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD));
org.openide.awt.Mnemonics.setLocalizedText(detectionSettingsLabel, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(includeExcludeCheckbox, org.openide.util.NbBundle.getMessage(PhotoRecCarverIngestJobSettingsPanel.class, "PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text")); // NOI18N
includeExcludeCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
includeExcludeCheckboxActionPerformed(evt);
}
});
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);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(keepCorruptedFilesCheckbox))
.addComponent(detectionSettingsLabel))
.addContainerGap(159, Short.MAX_VALUE))
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(detectionSettingsLabel)
.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.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(detectionSettingsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGap(0, 2, 2)
.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
private void includeExcludeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_includeExcludeCheckboxActionPerformed
setIncludePanelEnabled();
}//GEN-LAST:event_includeExcludeCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel detectionSettingsLabel;
private javax.swing.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;
// End of variables declaration//GEN-END:variables
}

View File

@ -36,7 +36,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
KeywordSearchResultFactory.query.exception.msg=Could not perform the query
OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
OpenIDE-Module-Name=KeywordSearch
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search

View File

@ -18,15 +18,18 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
@ -81,6 +84,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
if (i == 0) {
column.setPreferredWidth(((int) (width * 0.07)));
} else {
column.setCellRenderer(new KeywordTableCellRenderer());
column.setPreferredWidth(((int) (width * 0.92)));
}
}
@ -180,6 +184,25 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
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 {
@Override

View File

@ -131,7 +131,8 @@ def get_prop_entries(rows: List[List[str]],
should_delete_converter: Callable[[List[str]], bool] = None,
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:
rows (List[List[str]]): The csv file rows to parse.
@ -146,9 +147,11 @@ def get_prop_entries(rows: List[List[str]],
Returns:
List[PropEntry]: The generated prop entry objects.
"""
return map(lambda row: get_prop_entry(
row, path_idx, key_idx, value_idx, should_delete_converter, path_converter),
rows)
propentry_iter = map(lambda row: get_prop_entry(row, path_idx, key_idx, value_idx, should_delete_converter,
path_converter), 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:

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.

View File

@ -21,13 +21,11 @@ package org.sleuthkit.autopsy.thunderbirdparser;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import org.apache.james.mime4j.dom.BinaryBody;
import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
@ -227,11 +225,11 @@ class MimeJ4MessageParser {
} else if (e.getDispositionType() != null
&& e.getDispositionType().equals(ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT)) {
handleAttachment(email, e, fileID, index);
} else if (e.getMimeType().equals(HTML_TYPE)
|| e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN)) {
} else if ((e.getMimeType().equals(HTML_TYPE) && (email.getHtmlBody() == null || email.getHtmlBody().isEmpty()))
|| (e.getMimeType().equals(ContentTypeField.TYPE_TEXT_PLAIN) && (email.getTextBody() == null || email.getTextBody().isEmpty()))) {
handleTextBody(email, (TextBody) e.getBody(), e.getMimeType(), e.getHeader().getFields());
} else {
// Ignore other types.
handleAttachment(email, e, fileID, index);
}
}
}