3086-Fix merge conflict with OtherCasesTableModel

This commit is contained in:
William Schaefer 2017-09-27 13:40:27 -04:00
commit 3da10bca78
34 changed files with 1005 additions and 904 deletions

View File

@ -36,7 +36,7 @@ import javax.swing.event.DocumentListener;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
@ -48,7 +48,7 @@ import org.sleuthkit.autopsy.centralrepository.optionspanel.AddNewOrganizationDi
public class EamCaseEditDetailsDialog extends JDialog { public class EamCaseEditDetailsDialog extends JDialog {
private final static Logger LOGGER = Logger.getLogger(EamCaseEditDetailsDialog.class.getName()); private final static Logger LOGGER = Logger.getLogger(EamCaseEditDetailsDialog.class.getName());
private EamCase eamCase; private CorrelationCase eamCase;
private EamDb dbManager; private EamDb dbManager;
private Boolean contentChanged = false; private Boolean contentChanged = false;
private final Collection<JTextField> textBoxes = new ArrayList<>(); private final Collection<JTextField> textBoxes = new ArrayList<>();
@ -69,7 +69,7 @@ public class EamCaseEditDetailsDialog extends JDialog {
try { try {
this.dbManager = EamDb.getInstance(); this.dbManager = EamDb.getInstance();
this.eamCase = this.dbManager.getCaseDetails(Case.getCurrentCase().getName()); this.eamCase = this.dbManager.getCaseByUUID(Case.getCurrentCase().getName());
if(this.eamCase == null){ if(this.eamCase == null){
this.eamCase = dbManager.newCase(Case.getCurrentCase()); this.eamCase = dbManager.newCase(Case.getCurrentCase());
} }

View File

@ -50,7 +50,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamGlobalFileInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.EamGlobalFileInstance;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
@ -167,7 +167,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx); int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx);
CorrelationAttribute eamArtifact = (CorrelationAttribute) tableModel.getRow(selectedRowModelIdx); CorrelationAttribute eamArtifact = (CorrelationAttribute) tableModel.getRow(selectedRowModelIdx);
EamCase eamCasePartial = eamArtifact.getInstances().get(0).getEamCase(); CorrelationCase eamCasePartial = eamArtifact.getInstances().get(0).getCorrelationCase();
if (eamCasePartial == null) { if (eamCasePartial == null) {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference(), Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference(),
@ -177,7 +177,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
} }
caseDisplayName = eamCasePartial.getDisplayName(); caseDisplayName = eamCasePartial.getDisplayName();
// query case details // query case details
EamCase eamCase = dbManager.getCaseDetails(eamCasePartial.getCaseUUID()); CorrelationCase eamCase = dbManager.getCaseByUUID(eamCasePartial.getCaseUUID());
if (eamCase == null) { if (eamCase == null) {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(), Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
@ -421,9 +421,9 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
try { try {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
Collection<CorrelationAttributeInstance> artifactInstances = dbManager.getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).stream() Collection<CorrelationAttributeInstance> artifactInstances = dbManager.getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).stream()
.filter(artifactInstance -> !artifactInstance.getEamCase().getCaseUUID().equals(caseUUID) .filter(artifactInstance -> !artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID)
|| !artifactInstance.getEamDataSource().getName().equals(dataSourceName) || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName)
|| !artifactInstance.getEamDataSource().getDeviceID().equals(deviceId)) || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId))
.collect(Collectors.toList()); .collect(Collectors.toList());
return artifactInstances; return artifactInstances;
} catch (EamDbException ex) { } catch (EamDbException ex) {

View File

@ -49,7 +49,8 @@ public class DataContentViewerOtherCasesTableCellRenderer implements TableCellRe
foreground = Color.WHITE; foreground = Color.WHITE;
background = Color.BLUE; background = Color.BLUE;
} else { } else {
String known_status = (String) table.getModel().getValueAt(row, 5); String known_status = (String) table.getModel().getValueAt(row,
table.getColumn(DataContentViewerOtherCasesTableModel.TableColumns.KNOWN.columnName()).getModelIndex());
if (known_status.equals(TskData.FileKnown.BAD.getName())) { if (known_status.equals(TskData.FileKnown.BAD.getName())) {
foreground = Color.WHITE; foreground = Color.WHITE;
background = Color.RED; background = Color.RED;

View File

@ -40,7 +40,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
"DataContentViewerOtherCasesTableModel.known=Known", "DataContentViewerOtherCasesTableModel.known=Known",
"DataContentViewerOtherCasesTableModel.comment=Comment", "DataContentViewerOtherCasesTableModel.comment=Comment",
"DataContentViewerOtherCasesTableModel.noData=No Data.",}) "DataContentViewerOtherCasesTableModel.noData=No Data.",})
private enum TableColumns { enum TableColumns {
// Ordering here determines displayed column order in Content Viewer. // Ordering here determines displayed column order in Content Viewer.
// If order is changed, update the CellRenderer to ensure correct row coloring. // If order is changed, update the CellRenderer to ensure correct row coloring.
CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 100), CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 100),
@ -133,18 +133,18 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
switch (colId) { switch (colId) {
case CASE_NAME: case CASE_NAME:
if (null != eamArtifactInstance.getEamCase()) { if (null != eamArtifactInstance.getCorrelationCase()) {
value = eamArtifactInstance.getEamCase().getDisplayName(); value = eamArtifactInstance.getCorrelationCase().getDisplayName();
} }
break; break;
case DEVICE: case DEVICE:
if (null != eamArtifactInstance.getEamDataSource()) { if (null != eamArtifactInstance.getCorrelationDataSource()) {
value = eamArtifactInstance.getEamDataSource().getDeviceID(); value = eamArtifactInstance.getCorrelationDataSource().getDeviceID();
} }
break; break;
case DATA_SOURCE: case DATA_SOURCE:
if (null != eamArtifactInstance.getEamDataSource()) { if (null != eamArtifactInstance.getCorrelationDataSource()) {
value = eamArtifactInstance.getEamDataSource().getName(); value = eamArtifactInstance.getCorrelationDataSource().getName();
} }
break; break;
case FILE_PATH: case FILE_PATH:

View File

@ -198,7 +198,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @param eamCase The case to add * @param eamCase The case to add
*/ */
@Override @Override
public void newCase(EamCase eamCase) throws EamDbException { public void newCase(CorrelationCase eamCase) throws EamDbException {
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -259,12 +259,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @param case The case to add * @param case The case to add
*/ */
@Override @Override
public EamCase newCase(Case autopsyCase) throws EamDbException{ public CorrelationCase newCase(Case autopsyCase) throws EamDbException{
if(autopsyCase == null){ if(autopsyCase == null){
throw new EamDbException("Case is null"); throw new EamDbException("Case is null");
} }
EamCase curCeCase = new EamCase( CorrelationCase curCeCase = new CorrelationCase(
-1, -1,
autopsyCase.getName(), // unique case ID autopsyCase.getName(), // unique case ID
EamOrganization.getDefault(), EamOrganization.getDefault(),
@ -285,7 +285,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @param eamCase The case to update * @param eamCase The case to update
*/ */
@Override @Override
public void updateCase(EamCase eamCase) throws EamDbException { public void updateCase(CorrelationCase eamCase) throws EamDbException {
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -349,10 +349,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @return The retrieved case * @return The retrieved case
*/ */
@Override @Override
public EamCase getCaseDetails(String caseUUID) throws EamDbException { public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
// @@@ We should have a cache here...
Connection conn = connect(); Connection conn = connect();
EamCase eamCaseResult = null; CorrelationCase eamCaseResult = null;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
@ -386,11 +388,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @return List of cases * @return List of cases
*/ */
@Override @Override
public List<EamCase> getCases() throws EamDbException { public List<CorrelationCase> getCases() throws EamDbException {
Connection conn = connect(); Connection conn = connect();
List<EamCase> cases = new ArrayList<>(); List<CorrelationCase> cases = new ArrayList<>();
EamCase eamCaseResult; CorrelationCase eamCaseResult;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
@ -450,27 +452,27 @@ public abstract class AbstractSqlEamDb implements EamDb {
* *
* @param eamDataSource the data source to update * @param eamDataSource the data source to update
*/ */
@Override // @Override
public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { // public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
Connection conn = connect(); // Connection conn = connect();
// BC: This needs to be updated because device_id is not unique. Query needs to also use case_id
PreparedStatement preparedStatement = null; // PreparedStatement preparedStatement = null;
String sql = "UPDATE data_sources SET name=? WHERE device_id=?"; // String sql = "UPDATE data_sources SET name=? WHERE device_id=?";
//
try { // try {
preparedStatement = conn.prepareStatement(sql); // preparedStatement = conn.prepareStatement(sql);
//
preparedStatement.setString(1, eamDataSource.getName()); // preparedStatement.setString(1, eamDataSource.getName());
preparedStatement.setString(2, eamDataSource.getDeviceID()); // preparedStatement.setString(2, eamDataSource.getDeviceID());
//
preparedStatement.executeUpdate(); // preparedStatement.executeUpdate();
} catch (SQLException ex) { // } catch (SQLException ex) {
throw new EamDbException("Error updating case.", ex); // NON-NLS // throw new EamDbException("Error updating case.", ex); // NON-NLS
} finally { // } finally {
EamDbUtil.closePreparedStatement(preparedStatement); // EamDbUtil.closePreparedStatement(preparedStatement);
EamDbUtil.closeConnection(conn); // EamDbUtil.closeConnection(conn);
} // }
} // }
/** /**
* Retrieves Data Source details based on data source device ID * Retrieves Data Source details based on data source device ID
@ -568,8 +570,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement = conn.prepareStatement(sql.toString());
for (CorrelationAttributeInstance eamInstance : eamInstances) { for (CorrelationAttributeInstance eamInstance : eamInstances) {
if(! eamArtifact.getCorrelationValue().isEmpty()){ if(! eamArtifact.getCorrelationValue().isEmpty()){
preparedStatement.setString(1, eamInstance.getEamCase().getCaseUUID()); preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
preparedStatement.setString(2, eamInstance.getEamDataSource().getDeviceID()); preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
preparedStatement.setString(3, eamArtifact.getCorrelationValue()); preparedStatement.setString(3, eamArtifact.getCorrelationValue());
preparedStatement.setString(4, eamInstance.getFilePath()); preparedStatement.setString(4, eamInstance.getFilePath());
preparedStatement.setByte(5, eamInstance.getKnownStatus().getFileKnownValue()); preparedStatement.setByte(5, eamInstance.getKnownStatus().getFileKnownValue());
@ -928,8 +930,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
for (CorrelationAttributeInstance eamInstance : eamInstances) { for (CorrelationAttributeInstance eamInstance : eamInstances) {
if(! eamArtifact.getCorrelationValue().isEmpty()){ if(! eamArtifact.getCorrelationValue().isEmpty()){
bulkPs.setString(1, eamInstance.getEamCase().getCaseUUID()); bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
bulkPs.setString(2, eamInstance.getEamDataSource().getDeviceID()); bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
bulkPs.setString(3, eamArtifact.getCorrelationValue()); bulkPs.setString(3, eamArtifact.getCorrelationValue());
bulkPs.setString(4, eamInstance.getFilePath()); bulkPs.setString(4, eamInstance.getFilePath());
bulkPs.setByte(5, eamInstance.getKnownStatus().getFileKnownValue()); bulkPs.setByte(5, eamInstance.getKnownStatus().getFileKnownValue());
@ -962,7 +964,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* Executes a bulk insert of the cases * Executes a bulk insert of the cases
*/ */
@Override @Override
public void bulkInsertCases(List<EamCase> cases) throws EamDbException { public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
Connection conn = connect(); Connection conn = connect();
if (cases.isEmpty()) { if (cases.isEmpty()) {
@ -978,7 +980,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
+ getConflictClause(); + getConflictClause();
bulkPs = conn.prepareStatement(sql); bulkPs = conn.prepareStatement(sql);
for (EamCase eamCase : cases) { for (CorrelationCase eamCase : cases) {
bulkPs.setString(1, eamCase.getCaseUUID()); bulkPs.setString(1, eamCase.getCaseUUID());
if (null == eamCase.getOrg()) { if (null == eamCase.getOrg()) {
bulkPs.setNull(2, Types.INTEGER); bulkPs.setNull(2, Types.INTEGER);
@ -1075,8 +1077,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
try { try {
preparedQuery = conn.prepareStatement(sqlQuery.toString()); preparedQuery = conn.prepareStatement(sqlQuery.toString());
preparedQuery.setString(1, eamInstance.getEamCase().getCaseUUID()); preparedQuery.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
preparedQuery.setString(2, eamInstance.getEamDataSource().getDeviceID()); preparedQuery.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
preparedQuery.setString(3, eamArtifact.getCorrelationValue()); preparedQuery.setString(3, eamArtifact.getCorrelationValue());
preparedQuery.setString(4, eamInstance.getFilePath()); preparedQuery.setString(4, eamInstance.getFilePath());
resultSet = preparedQuery.executeQuery(); resultSet = preparedQuery.executeQuery();
@ -1103,12 +1105,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
// in the database, but we don't expect the user to be tagging large numbers // in the database, but we don't expect the user to be tagging large numbers
// of items (that didn't have the CE ingest module run on them) at once. // of items (that didn't have the CE ingest module run on them) at once.
if(null == getCaseDetails(eamInstance.getEamCase().getCaseUUID())){ if(null == getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID())){
newCase(eamInstance.getEamCase()); newCase(eamInstance.getCorrelationCase());
} }
if (null == getDataSourceDetails(eamInstance.getEamDataSource().getDeviceID())) { if (null == getDataSourceDetails(eamInstance.getCorrelationDataSource().getDeviceID())) {
newDataSource(eamInstance.getEamDataSource()); newDataSource(eamInstance.getCorrelationDataSource());
} }
eamArtifact.getInstances().get(0).setKnownStatus(knownStatus); eamArtifact.getInstances().get(0).setKnownStatus(knownStatus);
@ -1836,7 +1838,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* *
* @throws SQLException when an expected column name is not in the resultSet * @throws SQLException when an expected column name is not in the resultSet
*/ */
private EamCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException { private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException {
if (null == resultSet) { if (null == resultSet) {
return null; return null;
} }
@ -1853,8 +1855,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
resultSet.getString("poc_phone")); resultSet.getString("poc_phone"));
} }
EamCase eamCase = new EamCase(resultSet.getString("case_uid"), resultSet.getString("case_name")); CorrelationCase eamCase = new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name"));
eamCase.setID(resultSet.getInt("case_id"));
eamCase.setOrg(eamOrg); eamCase.setOrg(eamOrg);
eamCase.setCreationDate(resultSet.getString("creation_date")); eamCase.setCreationDate(resultSet.getString("creation_date"));
eamCase.setCaseNumber(resultSet.getString("case_number")); eamCase.setCaseNumber(resultSet.getString("case_number"));
@ -1911,7 +1912,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
return null; return null;
} }
CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance(
new EamCase(resultSet.getString("case_uid"), resultSet.getString("case_name")), new CorrelationCase(resultSet.getString("case_uid"), resultSet.getString("case_name")),
new CorrelationDataSource(-1, resultSet.getString("device_id"), resultSet.getString("name")), new CorrelationDataSource(-1, resultSet.getString("device_id"), resultSet.getString("name")),
resultSet.getString("file_path"), resultSet.getString("file_path"),
resultSet.getString("comment"), resultSet.getString("comment"),

View File

@ -53,52 +53,52 @@ public class CorrelationAttributeInstance implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String ID; private int ID;
private EamCase eamCase; private CorrelationCase correlationCase;
private CorrelationDataSource eamDataSource; private CorrelationDataSource correlationDataSource;
private String filePath; private String filePath;
private String comment; private String comment;
private TskData.FileKnown knownStatus; private TskData.FileKnown knownStatus;
private GlobalStatus globalStatus; private GlobalStatus globalStatus;
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
EamCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource CorrelationDataSource eamDataSource
) { ) {
this("", eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
} }
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
EamCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath String filePath
) { ) {
this("", eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
} }
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
EamCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath, String filePath,
String comment String comment
) { ) {
this("", eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
} }
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
EamCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath, String filePath,
String comment, String comment,
TskData.FileKnown knownStatus, TskData.FileKnown knownStatus,
GlobalStatus globalStatus GlobalStatus globalStatus
) { ) {
this("", eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus); this(-1, eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus);
} }
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
String ID, int ID,
EamCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath, String filePath,
String comment, String comment,
@ -106,8 +106,8 @@ public class CorrelationAttributeInstance implements Serializable {
GlobalStatus globalStatus GlobalStatus globalStatus
) { ) {
this.ID = ID; this.ID = ID;
this.eamCase = eamCase; this.correlationCase = eamCase;
this.eamDataSource = eamDataSource; this.correlationDataSource = eamDataSource;
// Lower case paths to normalize paths and improve correlation results, if this causes significant issues on case-sensitive file systems, remove // Lower case paths to normalize paths and improve correlation results, if this causes significant issues on case-sensitive file systems, remove
this.filePath = filePath.toLowerCase(); this.filePath = filePath.toLowerCase();
this.comment = comment; this.comment = comment;
@ -116,9 +116,9 @@ public class CorrelationAttributeInstance implements Serializable {
} }
public Boolean equals(CorrelationAttributeInstance otherInstance) { public Boolean equals(CorrelationAttributeInstance otherInstance) {
return ((this.getID().equals(otherInstance.getID())) return ((this.getID() == otherInstance.getID())
&& (this.getEamCase().equals(otherInstance.getEamCase())) && (this.getCorrelationCase().equals(otherInstance.getCorrelationCase()))
&& (this.getEamDataSource().equals(otherInstance.getEamDataSource())) && (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource()))
&& (this.getFilePath().equals(otherInstance.getFilePath())) && (this.getFilePath().equals(otherInstance.getFilePath()))
&& (this.getGlobalStatus().equals(otherInstance.getGlobalStatus())) && (this.getGlobalStatus().equals(otherInstance.getGlobalStatus()))
&& (this.getKnownStatus().equals(otherInstance.getKnownStatus())) && (this.getKnownStatus().equals(otherInstance.getKnownStatus()))
@ -128,8 +128,8 @@ public class CorrelationAttributeInstance implements Serializable {
@Override @Override
public String toString() { public String toString() {
return this.getID() return this.getID()
+ this.getEamCase().getCaseUUID() + this.getCorrelationCase().getCaseUUID()
+ this.getEamDataSource().getName() + this.getCorrelationDataSource().getName()
+ this.getFilePath() + this.getFilePath()
+ this.getGlobalStatus() + this.getGlobalStatus()
+ this.getKnownStatus() + this.getKnownStatus()
@ -137,45 +137,24 @@ public class CorrelationAttributeInstance implements Serializable {
} }
/** /**
* @return the ID * @return the database ID
*/ */
public String getID() { int getID() {
return ID; return ID;
} }
/**
* @param ID the ID to set
*/
public void setID(String ID) {
this.ID = ID;
}
/** /**
* @return the eamCase * @return the eamCase
*/ */
public EamCase getEamCase() { public CorrelationCase getCorrelationCase() {
return eamCase; return correlationCase;
}
/**
* @param eamCase the eamCase to set
*/
public void setEamCase(EamCase eamCase) {
this.eamCase = eamCase;
} }
/** /**
* @return the eamDataSource * @return the eamDataSource
*/ */
public CorrelationDataSource getEamDataSource() { public CorrelationDataSource getCorrelationDataSource() {
return eamDataSource; return correlationDataSource;
}
/**
* @param eamDataSource the eamDataSource to set
*/
public void setEamDataSource(CorrelationDataSource eamDataSource) {
this.eamDataSource = eamDataSource;
} }
/** /**
@ -185,14 +164,6 @@ public class CorrelationAttributeInstance implements Serializable {
return filePath; return filePath;
} }
/**
* @param filePath the filePath to set
*/
public void setFilePath(String filePath) {
// Lower case paths to normalize paths and improve correlation results, if this causes significant issues on case-sensitive file systems, remove
this.filePath = filePath.toLowerCase();
}
/** /**
* @return the comment * @return the comment
*/ */

View File

@ -29,13 +29,13 @@ import org.openide.util.NbBundle.Messages;
* Used to store info about a case. * Used to store info about a case.
* *
*/ */
public class EamCase implements Serializable { public class CorrelationCase implements Serializable {
private static long serialVersionUID = 1L; private static long serialVersionUID = 1L;
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)"); private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
private int ID; private int databaseId;
private String caseUUID; private String caseUUID; // globally unique
private EamOrganization org; private EamOrganization org;
private String displayName; private String displayName;
private String creationDate; private String creationDate;
@ -45,11 +45,20 @@ public class EamCase implements Serializable {
private String examinerPhone; private String examinerPhone;
private String notes; private String notes;
public EamCase(String caseUUID, String displayName) { /**
*
* @param caseUUID Globally unique identifier
* @param displayName
*/
public CorrelationCase(String caseUUID, String displayName) {
this(-1, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null); this(-1, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
} }
public EamCase(int ID, CorrelationCase(int ID, String caseUUID, String displayName) {
this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
}
public CorrelationCase(int ID,
String caseUUID, String caseUUID,
EamOrganization org, EamOrganization org,
String displayName, String displayName,
@ -59,7 +68,7 @@ public class EamCase implements Serializable {
String examinerEmail, String examinerEmail,
String examinerPhone, String examinerPhone,
String notes) { String notes) {
this.ID = ID; this.databaseId = ID;
this.caseUUID = caseUUID; this.caseUUID = caseUUID;
this.org = org; this.org = org;
this.displayName = displayName; this.displayName = displayName;
@ -149,18 +158,13 @@ public class EamCase implements Serializable {
} }
/** /**
* @return the ID * @return the database ID for the case or -1 if it is unknown (or not in the DB)
*/ */
public int getID() { int getID() {
return ID; // @@@ Should probably have some lazy logic here to lead the ID from the DB if it is -1
return databaseId;
} }
/**
* @param ID the ID to set
*/
public void setID(int ID) {
this.ID = ID;
}
/** /**
* @return the caseUUID * @return the caseUUID
@ -169,12 +173,6 @@ public class EamCase implements Serializable {
return caseUUID; return caseUUID;
} }
/**
* @param caseUUID the caseUUID to set
*/
public void setCaseUUID(String caseUUID) {
this.caseUUID = caseUUID;
}
/** /**
* @return the org * @return the org
@ -287,5 +285,4 @@ public class EamCase implements Serializable {
public void setNotes(String notes) { public void setNotes(String notes) {
this.notes = notes; this.notes = notes;
} }
} }

View File

@ -34,7 +34,7 @@ public class CorrelationDataSource implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final int dataSourceId; //< Id in the central repo private final int dataSourceId; //< Id in the central repo
private final String deviceID; private final String deviceID; //< Unique to its associated case (not necessarily globally unique)
private final String name; private final String name;
@ -73,7 +73,7 @@ public class CorrelationDataSource implements Serializable {
public String toString() { public String toString() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("("); str.append("(");
str.append("ID=").append(Integer.toString(getDataSourceID())); str.append("ID=").append(Integer.toString(getID()));
str.append(",deviceID=").append(getDeviceID()); str.append(",deviceID=").append(getDeviceID());
str.append(",name=").append(getName()); str.append(",name=").append(getName());
str.append(")"); str.append(")");
@ -81,13 +81,16 @@ public class CorrelationDataSource implements Serializable {
} }
/** /**
* Get the database row ID
*
* @return the ID * @return the ID
*/ */
public int getDataSourceID() { int getID() {
return dataSourceId; return dataSourceId;
} }
/** /**
* Get the device ID that is unique to the case
* @return the deviceID * @return the deviceID
*/ */
public String getDeviceID() { public String getDeviceID() {

View File

@ -97,7 +97,7 @@ public class EamArtifactUtil {
// make an instance for the BB source file // make an instance for the BB source file
CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance(
new EamCase(currentCase.getName(), currentCase.getDisplayName()), new CorrelationCase(currentCase.getName(), currentCase.getDisplayName()),
CorrelationDataSource.fromTSKDataSource(bbSourceFile.getDataSource()), CorrelationDataSource.fromTSKDataSource(bbSourceFile.getDataSource()),
bbSourceFile.getParentPath() + bbSourceFile.getName(), bbSourceFile.getParentPath() + bbSourceFile.getName(),
"", "",
@ -229,12 +229,7 @@ public class EamArtifactUtil {
final AbstractFile af = (AbstractFile) content; final AbstractFile af = (AbstractFile) content;
if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) if ( ! isValidCentralRepoFile(af)) {
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
|| (af.getKnown() == TskData.FileKnown.KNOWN)
|| (af.isDir() == true)
|| (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) {
return null; return null;
} }
@ -249,7 +244,7 @@ public class EamArtifactUtil {
CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID);
eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash()); eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash());
CorrelationAttributeInstance cei = new CorrelationAttributeInstance( CorrelationAttributeInstance cei = new CorrelationAttributeInstance(
new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()), new CorrelationCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()),
CorrelationDataSource.fromTSKDataSource(af.getDataSource()), CorrelationDataSource.fromTSKDataSource(af.getDataSource()),
af.getParentPath() + af.getName(), af.getParentPath() + af.getName(),
comment, comment,
@ -263,4 +258,38 @@ public class EamArtifactUtil {
return null; return null;
} }
} }
/**
* Check whether the given abstract file should be processed for
* the central repository.
* @param af The file to test
* @return true if the file should be added to the central repo, false otherwise
*/
public static boolean isValidCentralRepoFile(AbstractFile af){
if(af == null){
return false;
}
if(af.getKnown() == TskData.FileKnown.KNOWN){
return false;
}
switch (af.getType()){
case UNALLOC_BLOCKS:
case UNUSED_BLOCKS:
case SLACK:
case VIRTUAL_DIR:
case LOCAL_DIR:
return false;
case CARVED:
case DERIVED:
case LOCAL:
return true;
case FS:
return af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC);
default:
LOGGER.log(Level.WARNING, "Unexpected file type {0}", af.getType().getName());
return false;
}
}
} }

View File

@ -147,21 +147,21 @@ public interface EamDb {
* *
* @param eamCase The case to add * @param eamCase The case to add
*/ */
void newCase(EamCase eamCase) throws EamDbException; void newCase(CorrelationCase eamCase) throws EamDbException;
/** /**
* Creates new Case in the database from the given case * Creates new Case in the database from the given case
* *
* @param case The case to add * @param case The case to add
*/ */
EamCase newCase(Case autopsyCase) throws EamDbException; CorrelationCase newCase(Case autopsyCase) throws EamDbException;
/** /**
* Updates an existing Case in the database * Updates an existing Case in the database
* *
* @param eamCase The case to update * @param eamCase The case to update
*/ */
void updateCase(EamCase eamCase) throws EamDbException; void updateCase(CorrelationCase eamCase) throws EamDbException;
/** /**
* Retrieves Case details based on Case UUID * Retrieves Case details based on Case UUID
@ -170,14 +170,14 @@ public interface EamDb {
* *
* @return The retrieved case * @return The retrieved case
*/ */
EamCase getCaseDetails(String caseUUID) throws EamDbException; CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException;
/** /**
* Retrieves cases that are in DB. * Retrieves cases that are in DB.
* *
* @return List of cases * @return List of cases
*/ */
List<EamCase> getCases() throws EamDbException; List<CorrelationCase> getCases() throws EamDbException;
/** /**
* Creates new Data Source in the database * Creates new Data Source in the database
@ -191,7 +191,7 @@ public interface EamDb {
* *
* @param eamDataSource the data source to update * @param eamDataSource the data source to update
*/ */
void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException; //void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException;
/** /**
* Retrieves Data Source details based on data source device ID * Retrieves Data Source details based on data source device ID
@ -312,7 +312,7 @@ public interface EamDb {
/** /**
* Executes a bulk insert of the cases * Executes a bulk insert of the cases
*/ */
void bulkInsertCases(List<EamCase> cases) throws EamDbException; void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException;
/** /**
* Sets an eamArtifact instance to the given known status. If eamArtifact * Sets an eamArtifact instance to the given known status. If eamArtifact

View File

@ -271,7 +271,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @param case The case to add * @param case The case to add
*/ */
@Override @Override
public EamCase newCase(Case autopsyCase) throws EamDbException { public CorrelationCase newCase(Case autopsyCase) throws EamDbException {
try{ try{
acquireExclusiveLock(); acquireExclusiveLock();
return super.newCase(autopsyCase); return super.newCase(autopsyCase);
@ -288,7 +288,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @param eamCase The case to add * @param eamCase The case to add
*/ */
@Override @Override
public void newCase(EamCase eamCase) throws EamDbException { public void newCase(CorrelationCase eamCase) throws EamDbException {
try{ try{
acquireExclusiveLock(); acquireExclusiveLock();
super.newCase(eamCase); super.newCase(eamCase);
@ -303,7 +303,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @param eamCase The case to update * @param eamCase The case to update
*/ */
@Override @Override
public void updateCase(EamCase eamCase) throws EamDbException { public void updateCase(CorrelationCase eamCase) throws EamDbException {
try{ try{
acquireExclusiveLock(); acquireExclusiveLock();
super.updateCase(eamCase); super.updateCase(eamCase);
@ -320,10 +320,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @return The retrieved case * @return The retrieved case
*/ */
@Override @Override
public EamCase getCaseDetails(String caseUUID) throws EamDbException { public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
try{ try{
acquireSharedLock(); acquireSharedLock();
return super.getCaseDetails(caseUUID); return super.getCaseByUUID(caseUUID);
} finally { } finally {
releaseSharedLock(); releaseSharedLock();
} }
@ -335,7 +335,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @return List of cases * @return List of cases
*/ */
@Override @Override
public List<EamCase> getCases() throws EamDbException { public List<CorrelationCase> getCases() throws EamDbException {
try{ try{
acquireSharedLock(); acquireSharedLock();
return super.getCases(); return super.getCases();
@ -364,15 +364,15 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* *
* @param eamDataSource the data source to update * @param eamDataSource the data source to update
*/ */
@Override // @Override
public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { // public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
try{ // try{
acquireExclusiveLock(); // acquireExclusiveLock();
super.updateDataSource(eamDataSource); // super.updateDataSource(eamDataSource);
} finally { // } finally {
releaseExclusiveLock(); // releaseExclusiveLock();
} // }
} // }
/** /**
* Retrieves Data Source details based on data source device ID * Retrieves Data Source details based on data source device ID
@ -561,7 +561,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* Executes a bulk insert of the cases * Executes a bulk insert of the cases
*/ */
@Override @Override
public void bulkInsertCases(List<EamCase> cases) throws EamDbException { public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
try{ try{
acquireExclusiveLock(); acquireExclusiveLock();
super.bulkInsertCases(cases); super.bulkInsertCases(cases);

View File

@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
@ -279,7 +279,7 @@ public class CaseEventListener implements PropertyChangeListener {
LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS
} }
EamCase curCeCase = new EamCase( CorrelationCase curCeCase = new CorrelationCase(
-1, -1,
curCase.getName(), // unique case ID curCase.getName(), // unique case ID
EamOrganization.getDefault(), EamOrganization.getDefault(),
@ -298,7 +298,7 @@ public class CaseEventListener implements PropertyChangeListener {
try { try {
// NOTE: Cannot determine if the opened case is a new case or a reopened case, // NOTE: Cannot determine if the opened case is a new case or a reopened case,
// so check for existing name in DB and insert if missing. // so check for existing name in DB and insert if missing.
EamCase existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID()); CorrelationCase existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID());
if (null == existingCase) { if (null == existingCase) {
dbManager.newCase(curCeCase); dbManager.newCase(curCeCase);
@ -321,7 +321,7 @@ public class CaseEventListener implements PropertyChangeListener {
String newName = (String)evt.getNewValue(); String newName = (String)evt.getNewValue();
try { try {
// See if the case is in the database. If it is, update the display name. // See if the case is in the database. If it is, update the display name.
EamCase existingCase = dbManager.getCaseDetails(Case.getCurrentCase().getName()); CorrelationCase existingCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
if (null != existingCase) { if (null != existingCase) {
existingCase.setDisplayName(newName); existingCase.setDisplayName(newName);

View File

@ -51,7 +51,7 @@ public class IngestEventsListener {
private static final Logger LOGGER = Logger.getLogger(CorrelationAttribute.class.getName()); private static final Logger LOGGER = Logger.getLogger(CorrelationAttribute.class.getName());
final Collection<String> addedCeArtifactTrackerSet = new LinkedHashSet<>(); final Collection<String> recentlyAddedCeArtifacts = new LinkedHashSet<>();
private static int ceModuleInstanceCount = 0; private static int ceModuleInstanceCount = 0;
private final PropertyChangeListener pcl1 = new IngestModuleEventListener(); private final PropertyChangeListener pcl1 = new IngestModuleEventListener();
private final PropertyChangeListener pcl2 = new IngestJobEventListener(); private final PropertyChangeListener pcl2 = new IngestJobEventListener();
@ -139,7 +139,7 @@ public class IngestEventsListener {
for (CorrelationAttribute eamArtifact : convertedArtifacts) { for (CorrelationAttribute eamArtifact : convertedArtifacts) {
try { try {
// Only do something with this artifact if it's unique within the job // Only do something with this artifact if it's unique within the job
if (addedCeArtifactTrackerSet.add(eamArtifact.toString())) { if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
// Was it previously marked as bad? // Was it previously marked as bad?
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad". // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
// if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case, // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
@ -178,10 +178,10 @@ public class IngestEventsListener {
switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) { switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
case DATA_SOURCE_ANALYSIS_COMPLETED: { case DATA_SOURCE_ANALYSIS_COMPLETED: {
// clear the tracker to reduce memory usage // clear the tracker to reduce memory usage
// @@@ This isnt' entirely accurate to do here. We could have multiple if (getCeModuleInstanceCount() == 0) {
// ingest jobs at the same time recentlyAddedCeArtifacts.clear();
addedCeArtifactTrackerSet.clear(); }
//else another instance of the Correlation Engine Module is still being run.
} // DATA_SOURCE_ANALYSIS_COMPLETED } // DATA_SOURCE_ANALYSIS_COMPLETED
break; break;
} }

View File

@ -18,12 +18,11 @@
*/ */
package org.sleuthkit.autopsy.centralrepository.ingestmodule; package org.sleuthkit.autopsy.centralrepository.ingestmodule;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -41,6 +40,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -49,7 +49,6 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener;
import org.sleuthkit.datamodel.TskDataException;
/** /**
* Ingest module for inserting entries into the Central Repository database on * Ingest module for inserting entries into the Central Repository database on
@ -64,7 +63,7 @@ class IngestModule implements FileIngestModule {
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
private static final IngestModuleReferenceCounter warningMsgRefCounter = new IngestModuleReferenceCounter(); private static final IngestModuleReferenceCounter warningMsgRefCounter = new IngestModuleReferenceCounter();
private long jobId; private long jobId;
private EamCase eamCase; private CorrelationCase eamCase;
private CorrelationDataSource eamDataSource; private CorrelationDataSource eamDataSource;
private Blackboard blackboard; private Blackboard blackboard;
private CorrelationAttribute.Type filesType; private CorrelationAttribute.Type filesType;
@ -83,12 +82,7 @@ class IngestModule implements FileIngestModule {
blackboard = Case.getCurrentCase().getServices().getBlackboard(); blackboard = Case.getCurrentCase().getServices().getBlackboard();
if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) if (! EamArtifactUtil.isValidCentralRepoFile(af)) {
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
|| (af.getKnown() == TskData.FileKnown.KNOWN)
|| (af.isDir() == true)
|| (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) {
return ProcessResult.OK; return ProcessResult.OK;
} }
@ -216,7 +210,7 @@ class IngestModule implements FileIngestModule {
throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS
} }
jobId = context.getJobId(); jobId = context.getJobId();
eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()); eamCase = new CorrelationCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName());
try { try {
eamDataSource = CorrelationDataSource.fromTSKDataSource(context.getDataSource()); eamDataSource = CorrelationDataSource.fromTSKDataSource(context.getDataSource());
@ -256,9 +250,9 @@ class IngestModule implements FileIngestModule {
} }
// ensure we have this case defined in the EAM DB // ensure we have this case defined in the EAM DB
EamCase existingCase; CorrelationCase existingCase;
Case curCase = Case.getCurrentCase(); Case curCase = Case.getCurrentCase();
EamCase curCeCase = new EamCase( CorrelationCase curCeCase = new CorrelationCase(
-1, -1,
curCase.getName(), // unique case ID curCase.getName(), // unique case ID
EamOrganization.getDefault(), EamOrganization.getDefault(),
@ -270,7 +264,7 @@ class IngestModule implements FileIngestModule {
null, null,
null); null);
try { try {
existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID()); existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID());
if (existingCase == null) { if (existingCase == null) {
dbManager.newCase(curCeCase); dbManager.newCase(curCeCase);
} }

View File

@ -147,6 +147,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
public Action[] getActions(boolean context) { public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<>(); List<Action> actionsList = new ArrayList<>();
actionsList.addAll(Arrays.asList(super.getActions(true))); actionsList.addAll(Arrays.asList(super.getActions(true)));
if (!this.getDirectoryBrowseMode()) { if (!this.getDirectoryBrowseMode()) {
actionsList.add(new ViewContextAction(Bundle.FileNode_getActions_viewFileInDir_text(), this)); actionsList.add(new ViewContextAction(Bundle.FileNode_getActions_viewFileInDir_text(), this));
actionsList.add(null); // Creates an item separator actionsList.add(null); // Creates an item separator

View File

@ -77,7 +77,6 @@ public class SlackFileNode extends AbstractFsContentNode<AbstractFile> {
for (Action a : super.getActions(true)) { for (Action a : super.getActions(true)) {
actionsList.add(a); actionsList.add(a);
} }
if (!this.getDirectoryBrowseMode()) { if (!this.getDirectoryBrowseMode()) {
actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "SlackFileNode.viewFileInDir.text"), this.content)); actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "SlackFileNode.viewFileInDir.text"), this.content));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator

View File

@ -36,6 +36,7 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction;
/** /**
* This class is used to represent the "Node" for the volume. Its child is the * This class is used to represent the "Node" for the volume. Its child is the
@ -139,7 +140,7 @@ public class VolumeNode extends AbstractContentNode<Volume> {
for (Action a : super.getActions(true)) { for (Action a : super.getActions(true)) {
actionsList.add(a); actionsList.add(a);
} }
actionsList.add(new FileSystemDetailsAction(content));
actionsList.add(new NewWindowViewAction( actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this)); NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this));
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content)); actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));

View File

@ -3,7 +3,6 @@ HINT_DirectoryTreeTopComponent=This is a DirectoryTree window
OpenIDE-Module-Name=DirectoryTree OpenIDE-Module-Name=DirectoryTree
FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset: FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset:
FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type: FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type:
FileSystemDetailsPanel.genInfoLabel.text=General File Information
FileSystemDetailsPanel.jLabel2.text=bytes FileSystemDetailsPanel.jLabel2.text=bytes
FileSystemDetailsPanel.jLabel3.text=bytes FileSystemDetailsPanel.jLabel3.text=bytes
FileSystemDetailsPanel.fsTypeValue.text=... FileSystemDetailsPanel.fsTypeValue.text=...
@ -14,7 +13,6 @@ FileSystemDetailsPanel.blockCountValue.text=...
FileSystemDetailsPanel.rootInumValue.text=... FileSystemDetailsPanel.rootInumValue.text=...
FileSystemDetailsPanel.firstInumValue.text=... FileSystemDetailsPanel.firstInumValue.text=...
FileSystemDetailsPanel.lastInumValue.text=... FileSystemDetailsPanel.lastInumValue.text=...
FileSystemDetailsPanel.jLabel1.text=Detailed File Information
FileSystemDetailsPanel.volumeIDLabel.text=Volume ID: FileSystemDetailsPanel.volumeIDLabel.text=Volume ID:
FileSystemDetailsPanel.blockSizeLabel.text=Block Size: FileSystemDetailsPanel.blockSizeLabel.text=Block Size:
FileSystemDetailsPanel.blockCountLabel.text=Block Count: FileSystemDetailsPanel.blockCountLabel.text=Block Count:

View File

@ -3,7 +3,6 @@ HINT_DirectoryTreeTopComponent=\u3053\u308c\u306f\u30c7\u30a3\u30ec\u30af\u30c8\
OpenIDE-Module-Name=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30c4\u30ea\u30fc OpenIDE-Module-Name=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30c4\u30ea\u30fc
FileSystemDetailsPanel.imgOffsetLabel.text=\u30a4\u30e1\u30fc\u30b8\u30aa\u30d5\u30bb\u30c3\u30c8\uff1a FileSystemDetailsPanel.imgOffsetLabel.text=\u30a4\u30e1\u30fc\u30b8\u30aa\u30d5\u30bb\u30c3\u30c8\uff1a
FileSystemDetailsPanel.fsTypeLabel.text=\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30bf\u30a4\u30d7\uff1a FileSystemDetailsPanel.fsTypeLabel.text=\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30bf\u30a4\u30d7\uff1a
FileSystemDetailsPanel.genInfoLabel.text=\u30d5\u30a1\u30a4\u30eb\u4e00\u822c\u60c5\u5831
FileSystemDetailsPanel.jLabel2.text=\u30d0\u30a4\u30c8 FileSystemDetailsPanel.jLabel2.text=\u30d0\u30a4\u30c8
FileSystemDetailsPanel.jLabel3.text=\u30d0\u30a4\u30c8 FileSystemDetailsPanel.jLabel3.text=\u30d0\u30a4\u30c8
FileSystemDetailsPanel.fsTypeValue.text=... FileSystemDetailsPanel.fsTypeValue.text=...
@ -14,7 +13,6 @@ FileSystemDetailsPanel.blockCountValue.text=...
FileSystemDetailsPanel.rootInumValue.text=... FileSystemDetailsPanel.rootInumValue.text=...
FileSystemDetailsPanel.firstInumValue.text=... FileSystemDetailsPanel.firstInumValue.text=...
FileSystemDetailsPanel.lastInumValue.text=... FileSystemDetailsPanel.lastInumValue.text=...
FileSystemDetailsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30\u60c5\u5831
FileSystemDetailsPanel.volumeIDLabel.text=\u30dc\u30ea\u30e5\u30fc\u30e0ID\uff1a FileSystemDetailsPanel.volumeIDLabel.text=\u30dc\u30ea\u30e5\u30fc\u30e0ID\uff1a
FileSystemDetailsPanel.blockSizeLabel.text=\u30d6\u30ed\u30c3\u30af\u30b5\u30a4\u30ba\uff1a FileSystemDetailsPanel.blockSizeLabel.text=\u30d6\u30ed\u30c3\u30af\u30b5\u30a4\u30ba\uff1a
FileSystemDetailsPanel.blockCountLabel.text=\u30d6\u30ed\u30c3\u30af\u6570\uff1a FileSystemDetailsPanel.blockCountLabel.text=\u30d6\u30ed\u30c3\u30af\u6570\uff1a

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.directorytree; package org.sleuthkit.autopsy.directorytree;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
@ -42,6 +43,7 @@ import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.Volume;
/** /**
* A node filter (decorator) that sets the actions for a node in the tree view * A node filter (decorator) that sets the actions for a node in the tree view
@ -78,6 +80,7 @@ class DirectoryTreeFilterNode extends FilterNode {
public String getDisplayName() { public String getDisplayName() {
final Node orig = getOriginal(); final Node orig = getOriginal();
String name = orig.getDisplayName(); String name = orig.getDisplayName();
if (orig instanceof AbstractContentNode) { if (orig instanceof AbstractContentNode) {
AbstractFile file = getLookup().lookup(AbstractFile.class); AbstractFile file = getLookup().lookup(AbstractFile.class);
if ((file != null) && (false == (orig instanceof BlackboardArtifactNode))) { if ((file != null) && (false == (orig instanceof BlackboardArtifactNode))) {
@ -94,8 +97,7 @@ class DirectoryTreeFilterNode extends FilterNode {
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); //NON-NLS logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); //NON-NLS
} }
} } else if (orig instanceof BlackboardArtifactNode) {
else if (orig instanceof BlackboardArtifactNode) {
BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact(); BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact();
try { try {
int numAttachments = artifact.getChildrenCount(); int numAttachments = artifact.getChildrenCount();
@ -146,7 +148,6 @@ class DirectoryTreeFilterNode extends FilterNode {
} }
} }
return numVisibleChildren; return numVisibleChildren;
} }
@ -161,32 +162,10 @@ class DirectoryTreeFilterNode extends FilterNode {
@Override @Override
public Action[] getActions(boolean context) { public Action[] getActions(boolean context) {
List<Action> actions = new ArrayList<>(); List<Action> actions = new ArrayList<>();
final Content content = this.getLookup().lookup(Content.class); final Content content = this.getLookup().lookup(Content.class);
if (content != null) { if (content != null) {
actions.addAll(ExplorerNodeActionVisitor.getActions(content)); actions.addAll(Arrays.asList(super.getActions(true)));
Directory dir = this.getLookup().lookup(Directory.class);
if (dir != null) {
actions.add(ExtractAction.getInstance());
actions.add(new RunIngestModulesAction(dir));
}
final Image img = this.getLookup().lookup(Image.class);
final VirtualDirectory virtualDirectory = this.getLookup().lookup(VirtualDirectory.class);
boolean isRootVD = false;
if (virtualDirectory != null) {
try {
if (virtualDirectory.getParent() == null) {
isRootVD = true;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error determining the parent of the virtual directory", ex); // NON-NLS
}
}
if (img != null || isRootVD) {
actions.add(new FileSearchAction(NbBundle.getMessage(this.getClass(), "DirectoryTreeFilterNode.action.openFileSrcByAttr.text")));
actions.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
}
} }
actions.add(collapseAllAction); actions.add(collapseAllAction);
return actions.toArray(new Action[actions.size()]); return actions.toArray(new Action[actions.size()]);

View File

@ -0,0 +1,90 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2017 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.directorytree;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Action which opens a dialog containing the FileSystemDetailsPanel.
*/
final public class FileSystemDetailsAction extends AbstractAction {
private static final Logger logger = Logger.getLogger(FileSystemDetailsPanel.class.getName());
final Volume fsContent;
@NbBundle.Messages({"FileSystemDetailsAction.title.text=File System Details"})
public FileSystemDetailsAction(Volume content) {
super(Bundle.FileSystemDetailsAction_title_text());
enabled = false;
fsContent = content;
try {
if (!fsContent.getFileSystems().isEmpty()) {
enabled = true;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Unable to create FileSystemDetailsAction", ex);
}
}
@Override
public void actionPerformed(ActionEvent e) {
FileSystemDetailsDialog fsDetailsDialog = new FileSystemDetailsDialog();
fsDetailsDialog.display(fsContent);
}
private final class FileSystemDetailsDialog extends JDialog implements ActionListener {
private static final long serialVersionUID = 1L;
private FileSystemDetailsDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.FileSystemDetailsAction_title_text(),
false);
}
private void display(Volume content) {
FileSystemDetailsPanel fsPanel = new FileSystemDetailsPanel(content);
fsPanel.setOKButtonActionListener(this);
setContentPane(fsPanel);
pack();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
}
}

View File

@ -19,12 +19,12 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="-2" pref="367" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="OKButton" min="-2" pref="93" max="-2" attributes="0"/> <Component id="genInfoPanel" min="-2" pref="534" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="221" max="-2" attributes="0"/>
<Component id="jSplitPane1" min="-2" pref="786" max="-2" attributes="0"/> <Component id="OKButton" min="-2" pref="93" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
@ -35,10 +35,10 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jSplitPane1" min="-2" max="-2" attributes="0"/> <Component id="genInfoPanel" min="-2" pref="114" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="OKButton" min="-2" max="-2" attributes="0"/> <Component id="OKButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="1"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -51,14 +51,6 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
<Properties>
<Property name="dividerLocation" type="int" value="180"/>
<Property name="orientation" type="int" value="0"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="genInfoPanel"> <Container class="javax.swing.JPanel" name="genInfoPanel">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
@ -70,66 +62,58 @@
<Dimension value="[815, 170]"/> <Dimension value="[815, 170]"/>
</Property> </Property>
</Properties> </Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="top"/>
</Constraint>
</Constraints>
<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" alignment="0" attributes="0">
<EmptySpace min="-2" pref="95" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="fsTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="fsTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgOffsetLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="imgOffsetLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="volumeIDLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="volumeIDLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="blockSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="blockSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="108" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="genInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Component id="blockSizeValue" pref="112" max="32767" attributes="0"/>
<Component id="blockSizeValue" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="imgOffsetValue" alignment="0" max="32767" attributes="0"/>
<Component id="volumeIDValue" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgOffsetValue" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fsTypeValue" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/> <Component id="jLabel3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="33" max="-2" attributes="0"/> </Group>
<Component id="volumeIDValue" max="32767" attributes="0"/>
<Component id="fsTypeValue" alignment="0" min="-2" pref="145" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/> <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="blockCountLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="blockCountLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="rootInumLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="rootInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="firstInumLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="firstInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lastInumLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="lastInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="111" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lastInumValue" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="blockCountValue" pref="128" max="32767" attributes="0"/>
<Component id="firstInumValue" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="rootInumValue" alignment="0" max="32767" attributes="0"/>
<Component id="rootInumValue" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="firstInumValue" alignment="0" max="32767" attributes="0"/>
<Component id="blockCountValue" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="lastInumValue" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
</Group> <EmptySpace max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="245" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace pref="23" max="32767" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="genInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
@ -177,7 +161,7 @@
<Component id="lastInumLabel" min="-2" max="-2" attributes="0"/> <Component id="lastInumLabel" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<Component id="jSeparator1" pref="101" max="32767" attributes="1"/> <Component id="jSeparator1" max="32767" attributes="1"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -377,18 +361,6 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="genInfoLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="genInfoLabel" property="font" relativeSize="false" size="18"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.genInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator1"> <Component class="javax.swing.JSeparator" name="jSeparator1">
<Properties> <Properties>
<Property name="orientation" type="int" value="1"/> <Property name="orientation" type="int" value="1"/>
@ -420,59 +392,5 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="detailInfoPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[516, 293]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace pref="278" max="32767" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="276" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="235" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="jLabel1" property="font" relativeSize="false" size="18"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2017 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,15 +18,21 @@
*/ */
package org.sleuthkit.autopsy.directorytree; package org.sleuthkit.autopsy.directorytree;
import java.awt.*;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* This is the form / panel to show the File System Details. * This is the form / panel to show the File System Details.
* *
* @author jantonius * @author jantonius
*/ */
class FileSystemDetailsPanel extends javax.swing.JPanel { final class FileSystemDetailsPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(FileSystemDetailsPanel.class.getName());
private static final long serialVersionUID = 1L;
/** /**
* Creates new form FileSystemDetailsPanel * Creates new form FileSystemDetailsPanel
@ -35,6 +41,24 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
initComponents(); initComponents();
} }
FileSystemDetailsPanel(Volume content) {
initComponents();
try {
FileSystem fSystem = content.getFileSystems().get(0); //Autopsy currently only supports one file system per Volume
setFileSystemTypeValue(fSystem.getFsType().toString());
setImageOffsetValue(Long.toString(fSystem.getImageOffset()));
setVolumeIDValue(Long.toString(fSystem.getId()));
setBlockSizeValue(Long.toString(fSystem.getBlock_size()));
setBlockCountValue(Long.toString(fSystem.getBlock_count()));
setRootInumValue(Long.toString(fSystem.getRoot_inum()));
setFirstInumValue(Long.toString(fSystem.getFirst_inum()));
setLastInumValue(Long.toString(fSystem.getLastInum()));
} catch (TskCoreException|ArrayIndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Unable to construct FileSystemDetailsPanel",ex);
}
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -45,7 +69,6 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
private void initComponents() { private void initComponents() {
OKButton = new javax.swing.JButton(); OKButton = new javax.swing.JButton();
jSplitPane1 = new javax.swing.JSplitPane();
genInfoPanel = new javax.swing.JPanel(); genInfoPanel = new javax.swing.JPanel();
fsTypeLabel = new javax.swing.JLabel(); fsTypeLabel = new javax.swing.JLabel();
imgOffsetLabel = new javax.swing.JLabel(); imgOffsetLabel = new javax.swing.JLabel();
@ -63,18 +86,12 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
rootInumValue = new javax.swing.JLabel(); rootInumValue = new javax.swing.JLabel();
firstInumValue = new javax.swing.JLabel(); firstInumValue = new javax.swing.JLabel();
lastInumValue = new javax.swing.JLabel(); lastInumValue = new javax.swing.JLabel();
genInfoLabel = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JSeparator(); jSeparator1 = new javax.swing.JSeparator();
jLabel2 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel();
detailInfoPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
OKButton.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.OKButton.text")); // NOI18N OKButton.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.OKButton.text")); // NOI18N
jSplitPane1.setDividerLocation(180);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
genInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); genInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
genInfoPanel.setPreferredSize(new java.awt.Dimension(815, 170)); genInfoPanel.setPreferredSize(new java.awt.Dimension(815, 170));
@ -126,9 +143,6 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
lastInumValue.setFont(lastInumValue.getFont().deriveFont(lastInumValue.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); lastInumValue.setFont(lastInumValue.getFont().deriveFont(lastInumValue.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lastInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.lastInumValue.text")); // NOI18N lastInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.lastInumValue.text")); // NOI18N
genInfoLabel.setFont(genInfoLabel.getFont().deriveFont(genInfoLabel.getFont().getStyle() | java.awt.Font.BOLD, 18));
genInfoLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.genInfoLabel.text")); // NOI18N
jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL); jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
@ -142,47 +156,44 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
genInfoPanelLayout.setHorizontalGroup( genInfoPanelLayout.setHorizontalGroup(
genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(genInfoPanelLayout.createSequentialGroup() .addGroup(genInfoPanelLayout.createSequentialGroup()
.addGap(95, 95, 95) .addGap(10, 10, 10)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(fsTypeLabel) .addComponent(fsTypeLabel)
.addComponent(imgOffsetLabel) .addComponent(imgOffsetLabel)
.addComponent(volumeIDLabel) .addComponent(volumeIDLabel)
.addComponent(blockSizeLabel)) .addComponent(blockSizeLabel))
.addGap(108, 108, 108) .addGap(10, 10, 10)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(genInfoLabel)
.addGroup(genInfoPanelLayout.createSequentialGroup() .addGroup(genInfoPanelLayout.createSequentialGroup()
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(blockSizeValue) .addComponent(blockSizeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE)
.addComponent(volumeIDValue) .addComponent(imgOffsetValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(imgOffsetValue) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fsTypeValue))
.addGap(31, 31, 31)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2) .addComponent(jLabel2)
.addComponent(jLabel3)) .addComponent(jLabel3)))
.addGap(33, 33, 33) .addComponent(volumeIDValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(fsTypeValue, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(10, 10, 10)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(31, 31, 31) .addGap(10, 10, 10)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(blockCountLabel) .addComponent(blockCountLabel)
.addComponent(rootInumLabel) .addComponent(rootInumLabel)
.addComponent(firstInumLabel) .addComponent(firstInumLabel)
.addComponent(lastInumLabel)) .addComponent(lastInumLabel))
.addGap(111, 111, 111) .addGap(10, 10, 10)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lastInumValue) .addComponent(blockCountValue, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
.addComponent(firstInumValue) .addComponent(rootInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(rootInumValue) .addComponent(firstInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(blockCountValue)))) .addComponent(lastInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(245, 245, 245)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
genInfoPanelLayout.setVerticalGroup( genInfoPanelLayout.setVerticalGroup(
genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, genInfoPanelLayout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, genInfoPanelLayout.createSequentialGroup()
.addContainerGap(23, Short.MAX_VALUE) .addGap(10, 10, 10)
.addComponent(genInfoLabel)
.addGap(18, 18, 18)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -222,57 +233,30 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
.addComponent(firstInumLabel) .addComponent(firstInumLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lastInumLabel))) .addComponent(lastInumLabel)))
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)) .addComponent(jSeparator1))
.addContainerGap()) .addContainerGap())
); );
jSplitPane1.setTopComponent(genInfoPanel);
detailInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
detailInfoPanel.setPreferredSize(new java.awt.Dimension(516, 293));
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD, 18));
jLabel1.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.jLabel1.text")); // NOI18N
javax.swing.GroupLayout detailInfoPanelLayout = new javax.swing.GroupLayout(detailInfoPanel);
detailInfoPanel.setLayout(detailInfoPanelLayout);
detailInfoPanelLayout.setHorizontalGroup(
detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, detailInfoPanelLayout.createSequentialGroup()
.addContainerGap(278, Short.MAX_VALUE)
.addComponent(jLabel1)
.addGap(276, 276, 276))
);
detailInfoPanelLayout.setVerticalGroup(
detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(detailInfoPanelLayout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(jLabel1)
.addContainerGap(235, Short.MAX_VALUE))
);
jSplitPane1.setRightComponent(detailInfoPanel);
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(367, 367, 367)
.addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 786, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 534, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGap(221, 221, 221)
.addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .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(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(OKButton) .addComponent(OKButton)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
@ -364,20 +348,16 @@ class FileSystemDetailsPanel extends javax.swing.JPanel {
private javax.swing.JLabel blockCountValue; private javax.swing.JLabel blockCountValue;
private javax.swing.JLabel blockSizeLabel; private javax.swing.JLabel blockSizeLabel;
private javax.swing.JLabel blockSizeValue; private javax.swing.JLabel blockSizeValue;
private javax.swing.JPanel detailInfoPanel;
private javax.swing.JLabel firstInumLabel; private javax.swing.JLabel firstInumLabel;
private javax.swing.JLabel firstInumValue; private javax.swing.JLabel firstInumValue;
private javax.swing.JLabel fsTypeLabel; private javax.swing.JLabel fsTypeLabel;
private javax.swing.JLabel fsTypeValue; private javax.swing.JLabel fsTypeValue;
private javax.swing.JLabel genInfoLabel;
private javax.swing.JPanel genInfoPanel; private javax.swing.JPanel genInfoPanel;
private javax.swing.JLabel imgOffsetLabel; private javax.swing.JLabel imgOffsetLabel;
private javax.swing.JLabel imgOffsetValue; private javax.swing.JLabel imgOffsetValue;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel3;
private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JLabel lastInumLabel; private javax.swing.JLabel lastInumLabel;
private javax.swing.JLabel lastInumValue; private javax.swing.JLabel lastInumValue;
private javax.swing.JLabel rootInumLabel; private javax.swing.JLabel rootInumLabel;

View File

@ -72,8 +72,8 @@ public class ViewContextAction extends AbstractAction {
*/ */
public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) { public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) {
super(displayName); super(displayName);
this.content = artifactNode.getLookup().lookup(Content.class); this.content = artifactNode.getLookup().lookup(AbstractFile.class);
if (content instanceof AbstractFile) { if(this.content != null) {
AbstractFile file = (AbstractFile) content; AbstractFile file = (AbstractFile) content;
if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree()) if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree())
|| (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) { || (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) {

View File

@ -23,13 +23,12 @@ import java.awt.event.ActionEvent;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import org.openide.DialogDisplayer; import org.openide.DialogDisplayer;
import org.openide.WizardDescriptor; import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
@ -41,7 +40,7 @@ import org.sleuthkit.datamodel.Directory;
* When the data source is pressed, it should open the wizard for ingest * When the data source is pressed, it should open the wizard for ingest
* modules. * modules.
*/ */
public final class RunIngestModulesAction extends CallableSystemAction { public final class RunIngestModulesAction extends AbstractAction {
@Messages("RunIngestModulesAction.name=Run Ingest Modules") @Messages("RunIngestModulesAction.name=Run Ingest Modules")
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -51,6 +50,21 @@ public final class RunIngestModulesAction extends CallableSystemAction {
* used instead of this wizard and is retained for backwards compatibility. * used instead of this wizard and is retained for backwards compatibility.
*/ */
private static final String EXECUTION_CONTEXT = "org.sleuthkit.autopsy.ingest.RunIngestModulesDialog"; private static final String EXECUTION_CONTEXT = "org.sleuthkit.autopsy.ingest.RunIngestModulesDialog";
/**
* Display any warnings that the ingestJobSettings have.
*
* @param ingestJobSettings
*/
private static void showWarnings(IngestJobSettings ingestJobSettings) {
List<String> warnings = ingestJobSettings.getWarnings();
if (warnings.isEmpty() == false) {
StringBuilder warningMessage = new StringBuilder(1024);
for (String warning : warnings) {
warningMessage.append(warning).append("\n");
}
JOptionPane.showMessageDialog(null, warningMessage.toString());
}
}
private final List<Content> dataSources = new ArrayList<>(); private final List<Content> dataSources = new ArrayList<>();
private final IngestJobSettings.IngestType ingestType; private final IngestJobSettings.IngestType ingestType;
@ -103,35 +117,9 @@ public final class RunIngestModulesAction extends CallableSystemAction {
} }
} }
/**
* Display any warnings that the ingestJobSettings have.
*
* @param ingestJobSettings
*/
private static void showWarnings(IngestJobSettings ingestJobSettings) {
List<String> warnings = ingestJobSettings.getWarnings();
if (warnings.isEmpty() == false) {
StringBuilder warningMessage = new StringBuilder(1024);
for (String warning : warnings) {
warningMessage.append(warning).append("\n");
}
JOptionPane.showMessageDialog(null, warningMessage.toString());
}
}
@Override @Override
public void performAction() { public Object clone() throws CloneNotSupportedException {
actionPerformed(null); throw new CloneNotSupportedException("Clone is not supported for the RunIngestModulesAction");
} }
@Override
public String getName() {
return Bundle.RunIngestModulesAction_name();
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
} }

View File

@ -208,13 +208,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
* is set when the stage is set. * is set when the stage is set.
* *
* @param newStage The processing stage. * @param newStage The processing stage.
* @param stageStartDate The date and time this stage started.
*/ */
synchronized void setProcessingStage(Stage newStage) { synchronized void setProcessingStage(Stage newStage, Date stageStartDate) {
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newStage) { if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newStage) {
return; return;
} }
this.stage = newStage; this.stage = newStage;
this.stageStartDate = Date.from(Instant.now()); this.stageStartDate = stageStartDate;
} }
/** /**
@ -319,7 +320,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
* Cancels the job. * Cancels the job.
*/ */
synchronized void cancel() { synchronized void cancel() {
setProcessingStage(Stage.CANCELLING); setProcessingStage(Stage.CANCELLING, Date.from(Instant.now()));
cancelled = true; cancelled = true;
errorsOccurred = true; errorsOccurred = true;
if (null != dataSourceProcessor) { if (null != dataSourceProcessor) {
@ -347,7 +348,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
* the job. * the job.
*/ */
synchronized void setCompleted() { synchronized void setCompleted() {
setProcessingStage(Stage.COMPLETED); setProcessingStage(Stage.COMPLETED, Date.from(Instant.now()));
completed = true; completed = true;
} }

View File

@ -84,7 +84,7 @@ final class AutoIngestJobNodeData {
AutoIngestJobNodeData(AutoIngestJob job) { AutoIngestJobNodeData(AutoIngestJob job) {
setProcessingStatus(job.getProcessingStatus()); setProcessingStatus(job.getProcessingStatus());
setPriority(job.getPriority()); setPriority(job.getPriority());
setNumberOfCrashes(numberOfCrashes); // RJCTODO setNumberOfCrashes(job.getNumberOfCrashes());
setCompletedDate(job.getCompletedDate()); setCompletedDate(job.getCompletedDate());
setErrorsOccurred(job.getErrorsOccurred()); setErrorsOccurred(job.getErrorsOccurred());
this.version = CURRENT_VERSION; this.version = CURRENT_VERSION;

View File

@ -343,6 +343,10 @@ public final class AutoIngestManager extends Observable implements PropertyChang
hostNamesToRunningJobs.remove(hostName); hostNamesToRunningJobs.remove(hostName);
if (event.shouldRetry() == false) { if (event.shouldRetry() == false) {
synchronized (jobsLock) { synchronized (jobsLock) {
AutoIngestJob job = event.getJob();
if(completedJobs.contains(job)) {
completedJobs.remove(job);
}
completedJobs.add(event.getJob()); completedJobs.add(event.getJob());
} }
} }
@ -652,9 +656,14 @@ public final class AutoIngestManager extends Observable implements PropertyChang
*/ */
if (null != completedJob && !completedJob.getCaseDirectoryPath().toString().isEmpty()) { if (null != completedJob && !completedJob.getCaseDirectoryPath().toString().isEmpty()) {
try { try {
/**
* We reset the status, completion date and processing stage
* but we keep the original priority.
*/
completedJob.setErrorsOccurred(false); completedJob.setErrorsOccurred(false);
completedJob.setCompletedDate(new Date(0)); completedJob.setCompletedDate(new Date(0));
completedJob.setPriority(DEFAULT_JOB_PRIORITY); completedJob.setProcessingStatus(PENDING);
completedJob.setProcessingStage(AutoIngestJob.Stage.PENDING, Date.from(Instant.now()));
updateCoordinationServiceNode(completedJob); updateCoordinationServiceNode(completedJob);
pendingJobs.add(completedJob); pendingJobs.add(completedJob);
} catch (CoordinationServiceException ex) { } catch (CoordinationServiceException ex) {
@ -849,7 +858,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (null != ingestJob) { if (null != ingestJob) {
IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule(); IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule();
if (null != moduleHandle) { if (null != moduleHandle) {
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE); currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE, Date.from(Instant.now()));
moduleHandle.cancel(); moduleHandle.cancel();
SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()}); SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()});
} }
@ -1224,7 +1233,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
/* /*
* Update the coordination service node for the job. If * Update the coordination service node for the job. If
* this fails, leave the recovery to anoterh host. * this fails, leave the recovery to another host.
*/ */
try { try {
updateCoordinationServiceNode(job); updateCoordinationServiceNode(job);
@ -1294,13 +1303,26 @@ public final class AutoIngestManager extends Observable implements PropertyChang
private void addCompletedJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws CoordinationServiceException, InterruptedException { private void addCompletedJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws CoordinationServiceException, InterruptedException {
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
if (null != caseDirectoryPath) { if (null != caseDirectoryPath) {
/**
* We use the manifest rather than the nodeData here to create
* a new AutoIngestJob instance because the AutoIngestJob
* constructor that takes a nodeData expects the nodeData to
* have fields that do not exist in earlier versions.
*/
AutoIngestJob job = new AutoIngestJob(manifest); AutoIngestJob job = new AutoIngestJob(manifest);
/**
* Update the job with the fields that exist in all versions
* of the nodeData.
*/
job.setCompletedDate(nodeData.getCompletedDate());
job.setErrorsOccurred(nodeData.getErrorsOccurred());
job.setPriority(nodeData.getPriority());
job.setNumberOfCrashes(nodeData.getNumberOfCrashes());
job.setProcessingStage(AutoIngestJob.Stage.COMPLETED, nodeData.getCompletedDate());
job.setCaseDirectoryPath(caseDirectoryPath); job.setCaseDirectoryPath(caseDirectoryPath);
job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED);
job.setProcessingStage(AutoIngestJob.Stage.COMPLETED); newCompletedJobsList.add(job);
job.setCompletedDate(nodeData.getCompletedDate());
job.setErrorsOccurred(true);
newCompletedJobsList.add(new AutoIngestJob(nodeData));
/* /*
* Try to upgrade/update the coordination service node data for * Try to upgrade/update the coordination service node data for
@ -1868,7 +1890,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath);
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING); currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING); currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING, Date.from(Instant.now()));
currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME); currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME);
updateCoordinationServiceNode(currentJob); updateCoordinationServiceNode(currentJob);
setChanged(); setChanged();
@ -1990,7 +2012,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (AutoIngestUserPreferences.getSharedConfigEnabled()) { if (AutoIngestUserPreferences.getSharedConfigEnabled()) {
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG); currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now()));
new SharedConfiguration().downloadConfiguration(); new SharedConfiguration().downloadConfiguration();
} }
} }
@ -2008,7 +2030,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException { private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException {
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES); currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES, Date.from(Instant.now()));
if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) { if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) {
throw new DatabaseServerDownException("Case database server is down"); throw new DatabaseServerDownException("Case database server is down");
} }
@ -2055,7 +2077,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
String caseName = manifest.getCaseName(); String caseName = manifest.getCaseName();
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()}); SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE); currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE, Date.from(Instant.now()));
/* /*
* Acquire and hold a case name lock so that only one node at as * Acquire and hold a case name lock so that only one node at as
* time can scan the output directory at a time. This prevents * time can scan the output directory at a time. This prevents
@ -2168,7 +2190,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
DataSource dataSource = identifyDataSource(caseForJob); DataSource dataSource = identifyDataSource(caseForJob);
if (null == dataSource) { if (null == dataSource) {
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED); currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now()));
return; return;
} }
@ -2178,7 +2200,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
runDataSourceProcessor(caseForJob, dataSource); runDataSourceProcessor(caseForJob, dataSource);
if (dataSource.getContent().isEmpty()) { if (dataSource.getContent().isEmpty()) {
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED); currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now()));
return; return;
} }
@ -2223,7 +2245,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE, Date.from(Instant.now()));
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
Path dataSourcePath = manifest.getDataSourcePath(); Path dataSourcePath = manifest.getDataSourcePath();
@ -2259,7 +2281,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE, Date.from(Instant.now()));
UUID taskId = UUID.randomUUID(); UUID taskId = UUID.randomUUID();
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId); DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId);
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor(); DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
@ -2424,7 +2446,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE, Date.from(Instant.now()));
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
IngestJobEventListener ingestJobEventListener = new IngestJobEventListener(); IngestJobEventListener ingestJobEventListener = new IngestJobEventListener();
@ -2460,7 +2482,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
} }
jobLogger.logAnalysisCompleted(); jobLogger.logAnalysisCompleted();
} else { } else {
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING); currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING, Date.from(Instant.now()));
currentJob.setErrorsOccurred(true); currentJob.setErrorsOccurred(true);
AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log
jobLogger.logAnalysisCancelled(); jobLogger.logAnalysisCancelled();
@ -2523,7 +2545,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath);
currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES); currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES, Date.from(Instant.now()));
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
try { try {

View File

@ -55,6 +55,8 @@ class AccountsText implements IndexedText {
private static final Logger logger = Logger.getLogger(AccountsText.class.getName()); private static final Logger logger = Logger.getLogger(AccountsText.class.getName());
private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT); private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
private static final String CCN_REGEX = "(%?)(B?)([0-9][ \\-]*?){12,19}(\\^?)";
private static final String HIGHLIGHT_PRE = "<span style='background:yellow'>"; //NON-NLS private static final String HIGHLIGHT_PRE = "<span style='background:yellow'>"; //NON-NLS
private static final String ANCHOR_NAME_PREFIX = AccountsText.class.getName() + "_"; private static final String ANCHOR_NAME_PREFIX = AccountsText.class.getName() + "_";
@ -80,23 +82,24 @@ class AccountsText implements IndexedText {
private int numberPagesForFile = 0; private int numberPagesForFile = 0;
private Integer currentPage = 0; private Integer currentPage = 0;
/* /**
* map from page/chunk to number of hits. value is 0 if not yet known. * map from page/chunk to number of hits. value is 0 if not yet known.
*/ */
private final TreeMap<Integer, Integer> numberOfHitsPerPage = new TreeMap<>(); private final TreeMap<Integer, Integer> numberOfHitsPerPage = new TreeMap<>();
/*
/**
* set of pages, used for iterating back and forth. Only stores pages with * set of pages, used for iterating back and forth. Only stores pages with
* hits * hits
*/ */
private final Set<Integer> pages = numberOfHitsPerPage.keySet(); private final Set<Integer> pages = numberOfHitsPerPage.keySet();
/*
/**
* map from page/chunk number to current hit on that page. * map from page/chunk number to current hit on that page.
*/ */
private final HashMap<Integer, Integer> currentHitPerPage = new HashMap<>(); private final HashMap<Integer, Integer> currentHitPerPage = new HashMap<>();
AccountsText(long objectID, BlackboardArtifact artifact) { AccountsText(long objectID, BlackboardArtifact artifact) {
this(objectID, Arrays.asList(artifact)); this(objectID, Arrays.asList(artifact));
} }
@NbBundle.Messages({ @NbBundle.Messages({
@ -201,11 +204,7 @@ class AccountsText implements IndexedText {
@Override @Override
public int currentItem() { public int currentItem() {
if (this.currentHitPerPage.containsKey(currentPage)) { return currentHitPerPage.getOrDefault(currentPage, 0);
return currentHitPerPage.get(currentPage);
} else {
return 0;
}
} }
/** /**
@ -228,13 +227,9 @@ class AccountsText implements IndexedText {
//add both the canonical form and the form in the text as accountNumbers to highlight. //add both the canonical form and the form in the text as accountNumbers to highlight.
BlackboardAttribute attribute = artifact.getAttribute(TSK_KEYWORD); BlackboardAttribute attribute = artifact.getAttribute(TSK_KEYWORD);
if (attribute != null) {
this.accountNumbers.add(attribute.getValueString()); this.accountNumbers.add(attribute.getValueString());
}
attribute = artifact.getAttribute(TSK_CARD_NUMBER); attribute = artifact.getAttribute(TSK_CARD_NUMBER);
if (attribute != null) {
this.accountNumbers.add(attribute.getValueString()); this.accountNumbers.add(attribute.getValueString());
}
//if the chunk id is present just use that. //if the chunk id is present just use that.
Optional<Integer> chunkID = Optional<Integer> chunkID =
@ -249,6 +244,7 @@ class AccountsText implements IndexedText {
} else { } else {
//otherwise we need to do a query to figure out the paging. //otherwise we need to do a query to figure out the paging.
needsQuery = true; needsQuery = true;
// we can't break the for loop here because we need to accumulate all the accountNumbers
} }
} }
@ -265,10 +261,11 @@ class AccountsText implements IndexedText {
isPageInfoLoaded = true; isPageInfoLoaded = true;
} }
private static final String CCN_REGEX = "(%?)(B?)([0-9][ \\-]*?){12,19}(\\^?)";
/** /**
* Load the paging info from the QueryResults object. * Load the paging info from the QueryResults object.
*
* @param hits The QueryResults to load the paging info from.
*/ */
synchronized private void loadPageInfoFromHits(QueryResults hits) { synchronized private void loadPageInfoFromHits(QueryResults hits) {
//organize the hits by page, filter as needed //organize the hits by page, filter as needed
@ -374,9 +371,6 @@ class AccountsText implements IndexedText {
@Override @Override
public int getNumberHits() { public int getNumberHits() {
if (!this.numberOfHitsPerPage.containsKey(this.currentPage)) { return numberOfHitsPerPage.getOrDefault(currentPage, 0);
return 0;
}
return this.numberOfHitsPerPage.get(this.currentPage);
} }
} }

View File

@ -19,6 +19,11 @@
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.TreeRangeMap;
import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
@ -42,6 +47,73 @@ final class CreditCardValidator {
private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit(); private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit();
/**
* map from ccn IIN to allowed lengths
*/
static private final RangeMap<Integer, Set<Integer>> allowedLengths = TreeRangeMap.create();
private static final ImmutableSet<Integer> Set12to19 = ImmutableSet.of(12, 13, 14, 15, 16, 17, 18, 19);
private static final ImmutableSet<Integer> Set14to19 = ImmutableSet.of(14, 15, 16, 17, 18, 19);
private static final ImmutableSet<Integer> Set16to19 = ImmutableSet.of(16, 17, 18, 29);
static {
//amex
allowedLengths.put(Range.closedOpen(34000000, 35000000), ImmutableSet.of(15));
allowedLengths.put(Range.closedOpen(37000000, 38000000), ImmutableSet.of(15));
//visa
allowedLengths.put(Range.closedOpen(40000000, 50000000), Set12to19);
//visa electron
allowedLengths.put(Range.closedOpen(40260000, 40270000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(41750000, 41750100), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(44050000, 44060000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(45080000, 45090000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(48440000, 48450000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(49130000, 49140000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(49170000, 49180000), ImmutableSet.of(16));
//China UnionPay
allowedLengths.put(Range.closedOpen(62000000, 63000000), Set16to19);
//MasterCard
allowedLengths.put(Range.closedOpen(51000000, 56000000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(22210000, 27210000), ImmutableSet.of(16));
//Verve, these over lap with discover
allowedLengths.put(Range.closedOpen(50609900, 50619900), ImmutableSet.of(16, 19));
allowedLengths.put(Range.closedOpen(65000200, 65002700), ImmutableSet.of(16, 19));
//Maestro
allowedLengths.put(Range.closedOpen(50000000, 50100000), Set12to19);
allowedLengths.put(Range.closedOpen(56000000, 59000000), Set12to19);
allowedLengths.put(Range.closedOpen(60000000, 70000000), Set12to19);
allowedLengths.put(Range.closedOpen(63900000, 63910000), Set12to19);
allowedLengths.put(Range.closedOpen(67000000, 68000000), Set12to19);
//Diners Club International (processed by discover
allowedLengths.put(Range.closedOpen(30000000, 30600000), Set16to19);
allowedLengths.put(Range.closedOpen(30950000, 30960000), Set16to19);
allowedLengths.put(Range.closedOpen(36000000, 37000000), Set14to19);
allowedLengths.put(Range.closedOpen(38000000, 40000000), Set16to19);
//Diners Club USA & Canada (MasterCard co brand)
allowedLengths.put(Range.closedOpen(54000000, 56000000), Set14to19);
//Discover
allowedLengths.put(Range.closedOpen(60110000, 60120000), Set16to19);
allowedLengths.put(Range.closedOpen(62212600, 62292600), Set16to19);
allowedLengths.put(Range.closedOpen(64400000, 66000000), Set16to19);
//JCB //process by discover
allowedLengths.put(Range.closedOpen(35280000, 35900000), Set16to19);
//Dankort
allowedLengths.put(Range.closedOpen(50190000, 50200000), Set16to19);
//InterPayment
allowedLengths.put(Range.closedOpen(63600000, 63700000), Set16to19);
}
/** /**
* Does the given string represent a valid credit card number? It must have * Does the given string represent a valid credit card number? It must have
* no separators, or only '-', or only ' '. Checks digit grouping for * no separators, or only '-', or only ' '. Checks digit grouping for
@ -79,6 +151,10 @@ final class CreditCardValidator {
splitCCN = new String[]{cannonicalCCN}; splitCCN = new String[]{cannonicalCCN};
} }
if (false == lengthMatchesBin(cannonicalCCN)) {
return false;
}
// validate digit grouping for 15, 16, and 19 digit cards // validate digit grouping for 15, 16, and 19 digit cards
switch (cannonicalCCN.length()) { switch (cannonicalCCN.length()) {
case 15: case 15:
@ -105,6 +181,12 @@ final class CreditCardValidator {
return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN); return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN);
} }
static private boolean lengthMatchesBin(String cannonicalCCN) {
String BIN = cannonicalCCN.substring(0, 8);
final Set<Integer> lengthsForBIN = allowedLengths.get(Integer.valueOf(BIN));
return null == lengthsForBIN || lengthsForBIN.contains(cannonicalCCN.length());
}
static private boolean isValidOtherDigitGrouping(String[] splitCCN) { static private boolean isValidOtherDigitGrouping(String[] splitCCN) {
if (splitCCN.length == 1) { if (splitCCN.length == 1) {
return true; return true;

View File

@ -87,6 +87,7 @@ final class RegexQuery implements KeywordSearchQuery {
private static final int MAX_RESULTS_PER_CURSOR_MARK = 512; private static final int MAX_RESULTS_PER_CURSOR_MARK = 512;
private static final int MIN_EMAIL_ADDR_LENGTH = 8; private static final int MIN_EMAIL_ADDR_LENGTH = 8;
private static final String SNIPPET_DELIMITER = String.valueOf(Character.toChars(171));
private final List<KeywordQueryFilter> filters = new ArrayList<>(); private final List<KeywordQueryFilter> filters = new ArrayList<>();
private final KeywordList keywordList; private final KeywordList keywordList;
@ -149,7 +150,7 @@ final class RegexQuery implements KeywordSearchQuery {
final Server solrServer = KeywordSearch.getServer(); final Server solrServer = KeywordSearch.getServer();
SolrQuery solrQuery = new SolrQuery(); SolrQuery solrQuery = new SolrQuery();
/** /*
* The provided regular expression may include wildcards at the * The provided regular expression may include wildcards at the
* beginning and/or end. These wildcards are used to indicate that the * beginning and/or end. These wildcards are used to indicate that the
* user wants to find hits for the regex that are embedded within other * user wants to find hits for the regex that are embedded within other
@ -239,7 +240,6 @@ final class RegexQuery implements KeywordSearchQuery {
int offset = 0; int offset = 0;
while (hitMatcher.find(offset)) { while (hitMatcher.find(offset)) {
StringBuilder snippet = new StringBuilder();
// If the location of the hit is beyond this chunk (i.e. it // If the location of the hit is beyond this chunk (i.e. it
// exists in the overlap region), we skip the hit. It will // exists in the overlap region), we skip the hit. It will
@ -274,7 +274,7 @@ final class RegexQuery implements KeywordSearchQuery {
} }
if (artifactAttributeType == null) { if (artifactAttributeType == null) {
addHit(content, snippet, hitMatcher, hit, hits, docId); hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit));
} else { } else {
switch (artifactAttributeType) { switch (artifactAttributeType) {
case TSK_EMAIL: case TSK_EMAIL:
@ -285,7 +285,7 @@ final class RegexQuery implements KeywordSearchQuery {
*/ */
if (hit.length() >= MIN_EMAIL_ADDR_LENGTH if (hit.length() >= MIN_EMAIL_ADDR_LENGTH
&& DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) { && DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
addHit(content, snippet, hitMatcher, hit, hits, docId); hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit));
} }
break; break;
@ -302,15 +302,15 @@ final class RegexQuery implements KeywordSearchQuery {
if (ccnMatcher.find()) { if (ccnMatcher.find()) {
final String group = ccnMatcher.group("ccn"); final String group = ccnMatcher.group("ccn");
if (CreditCardValidator.isValidCCN(group)) { if (CreditCardValidator.isValidCCN(group)) {
addHit(content, snippet, hitMatcher, hit, hits, docId); hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit));
}; };
} }
} }
break; break;
default: default:
addHit(content, snippet, hitMatcher, hit, hits, docId); hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit));
break;
} }
} }
} }
@ -332,19 +332,28 @@ final class RegexQuery implements KeywordSearchQuery {
return hits; return hits;
} }
private void addHit(String content, StringBuilder snippet, Matcher hitMatcher, String hit, List<KeywordHit> hits, final String docId) throws TskCoreException {
/** /**
* Get the snippet from the document if keyword search is configured to * Make a snippet from the given content that has the given hit plus some
* use snippets. * surrounding context.
*
* @param content The content to extract the snippet from.
*
* @param hitMatcher The Matcher that has the start/end info for where the
* hit is in the content.
* @param hit The actual hit in the content.
*
* @return A snippet extracted from content that contains hit plus some
* surrounding context.
*/ */
private String makeSnippet(String content, Matcher hitMatcher, String hit) {
// Get the snippet from the document.
int maxIndex = content.length() - 1; int maxIndex = content.length() - 1;
snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start()))); final int end = hitMatcher.end();
snippet.appendCodePoint(171); final int start = hitMatcher.start();
snippet.append(hit);
snippet.appendCodePoint(171);
snippet.append(content.substring(Integer.min(maxIndex, hitMatcher.end()), Integer.min(maxIndex, hitMatcher.end() + 20)));
hits.add(new KeywordHit(docId, snippet.toString(), hit)); return content.substring(Integer.max(0, start - 20), Integer.max(0, start))
+ SNIPPET_DELIMITER + hit + SNIPPET_DELIMITER
+ content.substring(Integer.min(maxIndex, end), Integer.min(maxIndex, end + 20));
} }
@Override @Override
@ -559,7 +568,7 @@ final class RegexQuery implements KeywordSearchQuery {
*/ */
static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) { static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) {
BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType); BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType);
attributeMap.computeIfAbsent(type, (BlackboardAttribute.Type t) -> { attributeMap.computeIfAbsent(type, t -> {
String value = matcher.group(groupName); String value = matcher.group(groupName);
if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) { if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) {
attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD), attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD),
@ -568,8 +577,9 @@ final class RegexQuery implements KeywordSearchQuery {
} }
if (StringUtils.isNotBlank(value)) { if (StringUtils.isNotBlank(value)) {
return new BlackboardAttribute(attrType, MODULE_NAME, value); return new BlackboardAttribute(attrType, MODULE_NAME, value);
} } else {
return null; return null;
}
}); });
} }
} }

View File

@ -46,6 +46,50 @@ public class CreditCardValidatorTest {
public void tearDown() { public void tearDown() {
} }
@Test
public void testLengthMatchesBin() {
System.out.println("lengthMatchesBin");
//amex must be 15
assertEquals(true, CreditCardValidator.isValidCCN("3431 136294 58529"));
assertEquals(false, CreditCardValidator.isValidCCN("3431-136294-5850")); //too short
assertEquals(false, CreditCardValidator.isValidCCN("34311362945850"));// too short
assertEquals(false, CreditCardValidator.isValidCCN("3431 1362 9458 5034")); //too long
//verve 16 or 19
assertEquals(false, CreditCardValidator.isValidCCN("506099002418342")); // 15 too short
assertEquals(true, CreditCardValidator.isValidCCN("5060990024183426")); //16
assertEquals(false, CreditCardValidator.isValidCCN("50609900241834267")); // 17
assertEquals(false, CreditCardValidator.isValidCCN("506099002418342675")); //18
assertEquals(true, CreditCardValidator.isValidCCN("5060990024183426759")); //19
assertEquals(false, CreditCardValidator.isValidCCN("50609900241834267591")); //20
//visa (theoretically 12-19 digits)
assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 000")); //11 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002")); //12 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2")); //13 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 26")); //14 visa
assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 0002 267")); //15 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 000000 02267")); //15 visa //is this right to enforce grouping?
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675")); //16 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 9")); //17 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 91")); //18 visa
assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 918")); //19 visa
assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 0002 2675 9183")); //20 visa
//vs visa electron (only 16 digits (?))
assertEquals(false, CreditCardValidator.isValidCCN("4026 1200 006")); //11 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065")); //12 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9")); //13 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 91")); //14 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 918")); //15 visa electron
assertEquals(true, CreditCardValidator.isValidCCN("4026 0000 0065 9187")); //16 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9187 0")); //17 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 00")); //18 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 000")); //19 visa electron
assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 0000")); //20 visa electron
}
/** /**
* Test of isValidCCN method, of class CreditCardValidator. * Test of isValidCCN method, of class CreditCardValidator.
*/ */
@ -114,8 +158,7 @@ public class CreditCardValidatorTest {
assertEquals(true, CreditCardValidator.isValidCCN("623974 7947839518659")); assertEquals(true, CreditCardValidator.isValidCCN("623974 7947839518659"));
assertEquals(true, CreditCardValidator.isValidCCN("623974-7947839518659")); assertEquals(true, CreditCardValidator.isValidCCN("623974-7947839518659"));
/* /*
* China UnionPay may not use luhn ??? * China UnionPay may not use luhn ??? *
*
* https://stackoverflow.com/questions/7863058/does-the-luhn-algorithm-work-for-all-mainstream-credit-cards-discover-visa-m * https://stackoverflow.com/questions/7863058/does-the-luhn-algorithm-work-for-all-mainstream-credit-cards-discover-visa-m
*/ */
assertEquals(false, CreditCardValidator.isValidCCN("6239747947839518658")); //luhn assertEquals(false, CreditCardValidator.isValidCCN("6239747947839518658")); //luhn
@ -187,4 +230,5 @@ public class CreditCardValidatorTest {
assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators
} }
} }

View File

@ -138,7 +138,7 @@ The \ref content_viewer_page panel is where previous instances of properties are
If at least one other case or data source has been ingested with this module enabled, there is a potential that data will be displayed in the Other Occurrences content viewer. Note that the Correlation Engine Ingest Module does not have to have been run on the current data source to see correlated files from other cases/data sources. If the selected file or artifact is associated by one of the supported Correlation Types, to one or more file(s) or artifact(s) in the database, the associated files/artifacts will be displayed. Note: the Content Viewer will display ALL associated files and artifacts available in the database. It ignores the user's enabled/disabled Correlation Properties. If at least one other case or data source has been ingested with this module enabled, there is a potential that data will be displayed in the Other Occurrences content viewer. Note that the Correlation Engine Ingest Module does not have to have been run on the current data source to see correlated files from other cases/data sources. If the selected file or artifact is associated by one of the supported Correlation Types, to one or more file(s) or artifact(s) in the database, the associated files/artifacts will be displayed. Note: the Content Viewer will display ALL associated files and artifacts available in the database. It ignores the user's enabled/disabled Correlation Properties.
By default, the rows in the content viewer will have background colors to indicate if they are known to be of interest. Files/artifacts that are notable will have a Red background, unknown will have Yellow background, and known will have a White background. By default, the rows in the content viewer will have background colors to indicate if they are known to be of interest. Files/artifacts that are notable will have a Red background, all others will have a White background.
\image html central_repo_content_viewer.png \image html central_repo_content_viewer.png
@ -149,7 +149,7 @@ This menu has several options.
-# Select All -# Select All
-# Export Selected Rows to CSV -# Export Selected Rows to CSV
-# Show Case Details -# Show Case Details
-# Show Commonality Details -# Show Frequency
<b>Select All</b> <b>Select All</b>
@ -177,9 +177,9 @@ details will include:
These details would have been entered by the examiner of the selected case, by visiting These details would have been entered by the examiner of the selected case, by visiting
the Case -> Central Repository Case Properties menu, when that case was open. the Case -> Central Repository Case Properties menu, when that case was open.
<b>Show Commonality Details</b> <b>Show Frequency</b>
The concept of Commonality simply means, how common is the selected file. The value is the percentage of case/data source tuples that have the selected file or artifact. This shows how common the selected file is. The value is the percentage of case/data source tuples that have the selected file or artifact.
\subsection cr_interesting_items Interesting Items \subsection cr_interesting_items Interesting Items

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB