mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'release-4.5.0' of github.com:sleuthkit/autopsy into release-4.5.0
This commit is contained in:
commit
a524bd9a27
@ -1,77 +0,0 @@
|
||||
# Setting up the PostgreSQL DB for use in Enterprise Artifact Manager
|
||||
|
||||
## Using Command Line (cmd.exe)
|
||||
|
||||
The easiest way to do this is with the scripts that come with the PostgreSQL server.
|
||||
Add the PostgreSQL Server bin directory to your path in your user's environment
|
||||
variables.
|
||||
|
||||
PATH=$PATH;c:\Program Files\PostgreSQL\9.6\bin
|
||||
|
||||
Note: I've had issues getting these Windows PostgreSQL binaries to run in
|
||||
a cygwin terminal. But they work perfectly in cmd.exe.
|
||||
|
||||
### Create Role
|
||||
|
||||
The role we use has user name "testuser" and password "testpass".
|
||||
|
||||
$ createuser -U postgres -P testuser
|
||||
|
||||
When prompted for a password enter "testpass".
|
||||
|
||||
### Create Database
|
||||
|
||||
The database we use is named "enterpriseartifactmanagerdb".
|
||||
|
||||
$ createdb -T template0 -U postgres -O testuser enterpriseartifactmanagerdb
|
||||
|
||||
### Drop Database
|
||||
|
||||
If we want to reset the database, it's easiest to just drop it.
|
||||
|
||||
$ dropdb -U postgres enterpriseartifactmanagerdb
|
||||
|
||||
### Load the database content from a .sql file
|
||||
|
||||
Before loading a schema.sql file, you must have an empty database named
|
||||
enterpriseartifactmanagerdb and an existing user named testuser that is the database owner.
|
||||
Use the schema.sql files to create the tables, indices, and other required settings.
|
||||
|
||||
$ psql -U postgres enterpriseartifactmanagerdb < c:\path\to\schema.sql
|
||||
|
||||
## Using pgAdmin tool
|
||||
|
||||
### Create Role
|
||||
|
||||
Use the right-click menus to create a role named "testuser" with a password of
|
||||
"testpass".
|
||||
|
||||
### Create Database
|
||||
|
||||
Use the right-click menus to create a database named "enterpriseartifactmanagerdb"
|
||||
and set testuser as the owner.
|
||||
|
||||
### Load the database content from a .sql file
|
||||
|
||||
Right-click on the enterpriseartifactmanagerdb database and select "CREATE script".
|
||||
In the new window, delete all of the content and paste in the content of the
|
||||
schema.sql file.
|
||||
Click on the lightning icon to execute the contents you just pasted.
|
||||
|
||||
## Notes
|
||||
|
||||
- The schema.sql file does not contain commands to check for the existence of
|
||||
existing table objects, nor does it drop them before trying to add new ones.
|
||||
So, it is best to drop and create the database freshly before loading the schema.
|
||||
- pg_restore cannot load a .sql file.
|
||||
- The schema.sql file cannot have commands to drop/create the database.
|
||||
|
||||
### Purpose of each schema file
|
||||
|
||||
schema1 - 2 non-normalized tables, no FKs, no enforced uniqueness
|
||||
|
||||
schema2 - 2 non-normalized tables, no FKs, enforced uniqueness on artifacts
|
||||
- requires PostgreSQL Server ver 9.2+
|
||||
- postgresql automatically creates a unique index when a unique constraint is defined,
|
||||
so there is no need to manually create a unique index for the same column(s).
|
||||
Doing so would duplicate the automatically-created index.
|
@ -1,168 +0,0 @@
|
||||
# Mongo Database for testing
|
||||
|
||||
These instructions assume that you already have MongoDB Server 3.4 installed and
|
||||
that the server binary is at:
|
||||
|
||||
C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe
|
||||
|
||||
## Using multiple configurations
|
||||
|
||||
It is possible to use a configuration file and even to run MongoDB as a service,
|
||||
but for our testing, we want one instance that is the default non-secure instance.
|
||||
And we want a second instance that has auth enabled and has a defined role for
|
||||
our test user.
|
||||
|
||||
The the easiest way to have multiple instances of MongoDB that have
|
||||
unique configurations is to have each of them use distinct directories.
|
||||
|
||||
The default directories are:
|
||||
|
||||
C:\data\db
|
||||
C:\data\log
|
||||
|
||||
So, we need to create a second set of directories at:
|
||||
|
||||
C:\dataauth\db
|
||||
C:\dataauth\log
|
||||
|
||||
### Create config files, so it is easier to start MongoDB
|
||||
|
||||
The config file is YAML formatted, so do not use TABs. And every
|
||||
sub-level should be indented 2 spaces from the previous level.
|
||||
|
||||
We will not define the host/port values in the config files, because we assume
|
||||
that you are using the default port and host values AND
|
||||
that you will only run ONE of these two instances at a time.
|
||||
If you want them to run at the same time, include the net.port and net.bindIp
|
||||
parameters in the config file and make sure they are not both using the same
|
||||
port/IP pair.
|
||||
|
||||
The first config file is for the default instance, create a new file:
|
||||
|
||||
C:\data\mongod.cfg
|
||||
|
||||
Enter the following content into that file:
|
||||
|
||||
systemLog:
|
||||
destination: file
|
||||
path: c:\data\log\mongod.log
|
||||
storage:
|
||||
dbPath: c:\data\db
|
||||
|
||||
The second config file is for the auth instance, create a new file:
|
||||
|
||||
C:\dataauth\mongod.cfg
|
||||
|
||||
Enter the following content into that file:
|
||||
|
||||
systemLog:
|
||||
destination: file
|
||||
path: c:\dataauth\log\mongod.log
|
||||
storage:
|
||||
dbPath: c:\dataauth\db
|
||||
security:
|
||||
authorization: enabled
|
||||
|
||||
Note: Ensure Windows did not name your file ending with cfg.txt. You'll
|
||||
have to go to Folder Options -> View and uncheck the option to hide file extensions
|
||||
for common files.
|
||||
|
||||
Also, if you will be running mongod using a windows terminal (cmd.exe or powershell),
|
||||
make sure to use correct Windows path separators (i.e. c:\data\db).
|
||||
If you are instead using cygwin, make sure to use valid cygwin/unix path
|
||||
separators (i.e. c:/data/db).
|
||||
|
||||
### To start MongoDB using a config file
|
||||
|
||||
for Windows cmd or ps:
|
||||
|
||||
C:\path\to\bin\mongod.exe --config C:\data\mongod.cfg
|
||||
|
||||
or
|
||||
|
||||
C:\path\to\bin\mongod.exe --config C:\dataauth\mongod.cfg
|
||||
|
||||
for cygwin/unix:
|
||||
|
||||
cd /cygdrive/c/path/to/bin/
|
||||
./mongod.exe --config C:/data/mongod.cfg
|
||||
|
||||
or
|
||||
|
||||
./mongod.exe --config C:/dataauth/mongod.cfg
|
||||
|
||||
|
||||
If it starts correctly, you'll see nothing in the terminal and all logs will
|
||||
go to the specified log file.
|
||||
If there is a problem it will display an error in the terminal and fail to start.
|
||||
|
||||
### Setting up the auth'd instance
|
||||
|
||||
The first time you start this mongod instance, you MUST start with auth disabled,
|
||||
so it will let you create the admin user. Do this in the config file:
|
||||
|
||||
security:
|
||||
authorization: disabled
|
||||
|
||||
Now start the auth'd mongod in one terminal.
|
||||
|
||||
#### Create admin user
|
||||
|
||||
In a second terminal, connect to that instance with mongo client.
|
||||
|
||||
C:\path\to\mongo.exe
|
||||
|
||||
Enter the following in the mongo client:
|
||||
|
||||
use admin
|
||||
db.createUser(
|
||||
{
|
||||
user: "adminuser",
|
||||
pwd: "adminpass",
|
||||
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
|
||||
}
|
||||
)
|
||||
|
||||
Logout of the mongo client.
|
||||
Stop mongod.
|
||||
Set security.authorization to enabled in the auth'd mongod.cfg.
|
||||
Start the auth'd mongod.
|
||||
From now on, you can always start this instance of mongod with authorization
|
||||
enabled.
|
||||
|
||||
#### Create test user
|
||||
|
||||
In the second terminal, connect to the auth'd instance with mongo client.
|
||||
|
||||
C:\path\to\mongo.exe
|
||||
|
||||
Authenticate as the admin user:
|
||||
|
||||
use admin
|
||||
db.auth("adminuser", "adminpass")
|
||||
|
||||
Create the test user in the enterpriseartifactmanagerdb database with the readWrite role:
|
||||
|
||||
use enterpriseartifactmanagerdb
|
||||
db.createUser(
|
||||
{
|
||||
user: "testuser",
|
||||
pwd: "testpass",
|
||||
roles: [ { role: "readWrite", db: "enterpriseartifactmanagerdb" } ]
|
||||
}
|
||||
)
|
||||
|
||||
Now the EnterpriseArtifactManager code can use the user "testuser" to use the
|
||||
enterpriseartifactmanagerdb database. This includes creating/dropping indices/collections
|
||||
along with the usual insert/update/delete commands.
|
||||
|
||||
NOTE: The database where a user is created is that user's "authentication database".
|
||||
So, when that user needs to authenticate, they need to provide their username,
|
||||
password, and authentication database.
|
||||
|
||||
### References
|
||||
|
||||
Installation and setup: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/
|
||||
Config file: https://docs.mongodb.com/manual/reference/configuration-options/
|
||||
Enabling Auth: https://docs.mongodb.com/manual/tutorial/enable-authentication/
|
||||
readWrite Role: https://docs.mongodb.com/manual/reference/built-in-roles/#readWrite
|
@ -2,4 +2,4 @@ DataContentViewerOtherCases.selectAllMenuItem.text=Select All
|
||||
DataContentViewerOtherCases.showCaseDetailsMenuItem.text=Show Case Details
|
||||
DataContentViewerOtherCases.table.toolTip.text=Click column name to sort. Right-click on the table for more options.
|
||||
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export Selected Rows to CSV
|
||||
DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Commonality
|
||||
DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Frequency
|
||||
|
@ -47,8 +47,8 @@ import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
@ -73,18 +73,18 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
private final static Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
|
||||
|
||||
private final DataContentViewerOtherCasesTableModel tableModel;
|
||||
private final Collection<EamArtifact> correlatedArtifacts;
|
||||
private final Collection<CorrelationAttribute> correlationAttributes;
|
||||
|
||||
/**
|
||||
* Creates new form DataContentViewerOtherCases
|
||||
*/
|
||||
public DataContentViewerOtherCases() {
|
||||
this.tableModel = new DataContentViewerOtherCasesTableModel();
|
||||
this.correlatedArtifacts = new ArrayList<>();
|
||||
this.correlationAttributes = new ArrayList<>();
|
||||
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
readSettings();
|
||||
reset();
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
@ -119,11 +119,14 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
"# {0} - commonality percentage",
|
||||
"# {1} - correlation type",
|
||||
"# {2} - correlation value",
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.byType={0}% for Correlation Type: {1} and Correlation Value: {2}.\n",
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.title=Commonality Percentages",
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get commonality details."})
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.title=Attribute Frequency",
|
||||
"DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get frequency details."})
|
||||
/**
|
||||
* Show how common the selected
|
||||
*/
|
||||
private void showCommonalityDetails() {
|
||||
if (correlatedArtifacts.isEmpty()) {
|
||||
if (correlationAttributes.isEmpty()) {
|
||||
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
|
||||
Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
|
||||
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
|
||||
@ -133,8 +136,8 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
int percentage;
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
for (EamArtifact eamArtifact : correlatedArtifacts) {
|
||||
percentage = dbManager.getCommonalityPercentageForTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||
for (CorrelationAttribute eamArtifact : correlationAttributes) {
|
||||
percentage = dbManager.getFrequencyPercentage(eamArtifact);
|
||||
msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
|
||||
eamArtifact.getCorrelationType().getDisplayName(),
|
||||
eamArtifact.getCorrelationValue()));
|
||||
@ -163,7 +166,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
if (-1 != selectedRowViewIdx) {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx);
|
||||
EamArtifact eamArtifact = (EamArtifact) tableModel.getRow(selectedRowModelIdx);
|
||||
CorrelationAttribute eamArtifact = (CorrelationAttribute) tableModel.getRow(selectedRowModelIdx);
|
||||
EamCase eamCasePartial = eamArtifact.getInstances().get(0).getEamCase();
|
||||
if (eamCasePartial == null) {
|
||||
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
|
||||
@ -262,14 +265,12 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the module settings from the config file and reset the table model.
|
||||
* Reset the UI and clear cached data.
|
||||
*/
|
||||
private boolean readSettings() {
|
||||
private void reset() {
|
||||
// start with empty table
|
||||
tableModel.clearTable();
|
||||
correlatedArtifacts.clear();
|
||||
|
||||
return true;
|
||||
correlationAttributes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -294,7 +295,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
|
||||
@Override
|
||||
public void resetComponent() {
|
||||
readSettings();
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -365,102 +366,61 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a Node for blackboard artifacts / content that we can correlate on
|
||||
* and create the corresponding Central Repository artifacts for display
|
||||
* Determine what attributes can be used for correlation based on the node.
|
||||
*
|
||||
* @param node The node to view
|
||||
* @param node The node to correlate
|
||||
*
|
||||
* @return A collection of central repository artifacts to display
|
||||
* @return A list of attributes that can be used for correlation
|
||||
*/
|
||||
private Collection<EamArtifact> getArtifactsFromCorrelatableAttributes(Node node) {
|
||||
Collection<EamArtifact> ret = new ArrayList<>();
|
||||
private Collection<CorrelationAttribute> getCorrelationAttributesFromNode(Node node) {
|
||||
Collection<CorrelationAttribute> ret = new ArrayList<>();
|
||||
|
||||
/*
|
||||
* If the user selected a blackboard artifact or tag of a BB artifact,
|
||||
* correlate both the artifact and the associated file. If the user
|
||||
* selected a file, correlate only the file
|
||||
*/
|
||||
BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
|
||||
AbstractFile abstractFile = getAbstractFileFromNode(node);
|
||||
List<EamArtifact.Type> artifactTypes = null;
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
artifactTypes = dbManager.getCorrelationTypes();
|
||||
if (bbArtifact != null) {
|
||||
ret.addAll(EamArtifactUtil.fromBlackboardArtifact(bbArtifact, false, artifactTypes, false));
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error retrieving correlation types", ex); // NON-NLS
|
||||
// correlate on blackboard artifact attributes if they exist and supported
|
||||
BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
|
||||
if (bbArtifact != null) {
|
||||
ret.addAll(EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, false, false));
|
||||
}
|
||||
|
||||
|
||||
// we can correlate based on the MD5 if it is enabled
|
||||
AbstractFile abstractFile = getAbstractFileFromNode(node);
|
||||
if (abstractFile != null) {
|
||||
String md5 = abstractFile.getMd5Hash();
|
||||
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
|
||||
for (EamArtifact.Type aType : artifactTypes) {
|
||||
if (aType.getId() == EamArtifact.FILES_TYPE_ID) {
|
||||
ret.add(new EamArtifact(aType, md5));
|
||||
break;
|
||||
try {
|
||||
List<CorrelationAttribute.Type> artifactTypes = EamDb.getInstance().getDefinedCorrelationTypes();
|
||||
String md5 = abstractFile.getMd5Hash();
|
||||
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
|
||||
for (CorrelationAttribute.Type aType : artifactTypes) {
|
||||
if (aType.getId() == CorrelationAttribute.FILES_TYPE_ID) {
|
||||
ret.add(new CorrelationAttribute(aType, md5));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node, return the associated data source
|
||||
*
|
||||
* @param node The node
|
||||
*
|
||||
* @return The name of the data source
|
||||
*/
|
||||
private String getDataSourceNameFromNode(Node node) {
|
||||
AbstractFile af = getAbstractFileFromNode(node);
|
||||
try {
|
||||
if (af != null) {
|
||||
return af.getDataSource().getName();
|
||||
}
|
||||
} catch (TskException ex) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node, return the associated data source's device ID
|
||||
*
|
||||
* @param node The node
|
||||
*
|
||||
* @return The ID of the data source's device
|
||||
*/
|
||||
private String getDeviceIdFromNode(Node node) {
|
||||
AbstractFile af = getAbstractFileFromNode(node);
|
||||
try {
|
||||
if (af != null) {
|
||||
return Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
|
||||
}
|
||||
} catch (TskException ex) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the db for artifact instances from other cases correlated to the
|
||||
* given central repository artifact.
|
||||
* given central repository artifact. Will not show instances from the same datasource / device
|
||||
*
|
||||
* @param eamArtifact The artifact to correlate against
|
||||
* @param corAttr CorrelationAttribute to query for
|
||||
* @param dataSourceName Data source to filter results
|
||||
* @param deviceId Device Id to filter results
|
||||
*
|
||||
* @return A collection of correlated artifact instances from other cases
|
||||
*/
|
||||
private Collection<EamArtifactInstance> getCorrelatedInstances(EamArtifact.Type aType, String value, String dataSourceName, String deviceId) {
|
||||
private Collection<CorrelationAttributeInstance> getCorrelatedInstances(CorrelationAttribute corAttr, String dataSourceName, String deviceId) {
|
||||
// @@@ Check exception
|
||||
String caseUUID = Case.getCurrentCase().getName();
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
Collection<EamArtifactInstance> artifactInstances = dbManager.getArtifactInstancesByTypeValue(aType, value).stream()
|
||||
Collection<CorrelationAttributeInstance> artifactInstances = dbManager.getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).stream()
|
||||
.filter(artifactInstance -> !artifactInstance.getEamCase().getCaseUUID().equals(caseUUID)
|
||||
|| !artifactInstance.getEamDataSource().getName().equals(dataSourceName)
|
||||
|| !artifactInstance.getEamDataSource().getDeviceID().equals(deviceId))
|
||||
@ -475,25 +435,25 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
|
||||
/**
|
||||
* Get the global file instances matching the given eamArtifact and convert
|
||||
* them to central repository artifact instancess.
|
||||
* them to central repository artifact instances.
|
||||
*
|
||||
* @param eamArtifact Artifact to use for ArtifactTypeEnum matching
|
||||
*
|
||||
* @return List of central repository artifact instances, empty list if none
|
||||
* found
|
||||
*/
|
||||
public Collection<EamArtifactInstance> getReferenceInstancesAsArtifactInstances(EamArtifact eamArtifact) {
|
||||
Collection<EamArtifactInstance> eamArtifactInstances = new ArrayList<>();
|
||||
public Collection<CorrelationAttributeInstance> getReferenceInstancesAsArtifactInstances(CorrelationAttribute eamArtifact) {
|
||||
Collection<CorrelationAttributeInstance> eamArtifactInstances = new ArrayList<>();
|
||||
// FUTURE: support other reference types
|
||||
if (eamArtifact.getCorrelationType().getId() != EamArtifact.FILES_TYPE_ID) {
|
||||
if (eamArtifact.getCorrelationType().getId() != CorrelationAttribute.FILES_TYPE_ID) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
Collection<EamGlobalFileInstance> eamGlobalFileInstances = dbManager.getReferenceInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||
eamGlobalFileInstances.forEach((eamGlobalFileInstance) -> {
|
||||
eamArtifactInstances.add(new EamArtifactInstance(
|
||||
null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus(), EamArtifactInstance.GlobalStatus.GLOBAL
|
||||
eamArtifactInstances.add(new CorrelationAttributeInstance(
|
||||
null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus(), CorrelationAttributeInstance.GlobalStatus.GLOBAL
|
||||
));
|
||||
});
|
||||
return eamArtifactInstances;
|
||||
@ -510,7 +470,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
}
|
||||
|
||||
// Is supported if this node has correlatable content (File, BlackboardArtifact)
|
||||
return !getArtifactsFromCorrelatableAttributes(node).isEmpty();
|
||||
return !getCorrelationAttributesFromNode(node).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -520,7 +480,10 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
return;
|
||||
}
|
||||
|
||||
readSettings(); // reset the table to empty.
|
||||
reset(); // reset the table to empty.
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
populateTable(node);
|
||||
}
|
||||
|
||||
@ -533,26 +496,40 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
@Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other occurrences to display.",
|
||||
"DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file."})
|
||||
private void populateTable(Node node) {
|
||||
String dataSourceName = getDataSourceNameFromNode(node);
|
||||
String deviceId = getDeviceIdFromNode(node);
|
||||
correlatedArtifacts.addAll(getArtifactsFromCorrelatableAttributes(node));
|
||||
correlatedArtifacts.forEach((eamArtifact) -> {
|
||||
// get local instances
|
||||
Collection<EamArtifactInstance> eamArtifactInstances = getCorrelatedInstances(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue(), dataSourceName, deviceId);
|
||||
// get global instances
|
||||
eamArtifactInstances.addAll(getReferenceInstancesAsArtifactInstances(eamArtifact));
|
||||
AbstractFile af = getAbstractFileFromNode(node);
|
||||
String dataSourceName = "";
|
||||
String deviceId = "";
|
||||
try {
|
||||
if (af != null) {
|
||||
Content dataSource = af.getDataSource();
|
||||
dataSourceName = dataSource.getName();
|
||||
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(dataSource.getId()).getDeviceId();
|
||||
}
|
||||
} catch (TskException ex) {
|
||||
// do nothing.
|
||||
// @@@ Review this behavior
|
||||
}
|
||||
|
||||
// get the attributes we can correlate on
|
||||
correlationAttributes.addAll(getCorrelationAttributesFromNode(node));
|
||||
for (CorrelationAttribute corAttr : correlationAttributes) {
|
||||
Collection<CorrelationAttributeInstance> corAttrInstances = new ArrayList<>();
|
||||
|
||||
// get correlation and reference set instances from DB
|
||||
corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
|
||||
corAttrInstances.addAll(getReferenceInstancesAsArtifactInstances(corAttr));
|
||||
|
||||
eamArtifactInstances.forEach((eamArtifactInstance) -> {
|
||||
EamArtifact newCeArtifact = new EamArtifact(
|
||||
eamArtifact.getCorrelationType(),
|
||||
eamArtifact.getCorrelationValue()
|
||||
corAttrInstances.forEach((corAttrInstance) -> {
|
||||
CorrelationAttribute newCeArtifact = new CorrelationAttribute(
|
||||
corAttr.getCorrelationType(),
|
||||
corAttr.getCorrelationValue()
|
||||
);
|
||||
newCeArtifact.addInstance(eamArtifactInstance);
|
||||
newCeArtifact.addInstance(corAttrInstance);
|
||||
tableModel.addEamArtifact(newCeArtifact);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (correlatedArtifacts.isEmpty()) {
|
||||
if (correlationAttributes.isEmpty()) {
|
||||
displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_noArtifacts());
|
||||
} else if (0 == tableModel.getRowCount()) {
|
||||
displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_isempty());
|
||||
|
@ -55,7 +55,8 @@ public class DataContentViewerOtherCasesTableCellRenderer implements TableCellRe
|
||||
background = Color.RED;
|
||||
} else if (known_status.equals(TskData.FileKnown.UNKNOWN.getName())) {
|
||||
foreground = Color.BLACK;
|
||||
background = Color.YELLOW;
|
||||
//background = Color.YELLOW;
|
||||
background = Color.WHITE;
|
||||
} else {
|
||||
foreground = Color.BLACK;
|
||||
background = Color.WHITE;
|
||||
|
@ -22,8 +22,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
|
||||
/**
|
||||
* Model for cells in data content viewer table
|
||||
@ -45,13 +45,13 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
// If order is changed, update the CellRenderer to ensure correct row coloring.
|
||||
CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 75),
|
||||
DATA_SOURCE(Bundle.DataContentViewerOtherCasesTableModel_dataSource(), 75),
|
||||
DEVICE(Bundle.DataContentViewerOtherCasesTableModel_device(), 145),
|
||||
TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 40),
|
||||
VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 145),
|
||||
KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 45),
|
||||
SCOPE(Bundle.DataContentViewerOtherCasesTableModel_scope(), 20),
|
||||
COMMENT(Bundle.DataContentViewerOtherCasesTableModel_comment(), 200),
|
||||
FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 250);
|
||||
FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 250),
|
||||
DEVICE(Bundle.DataContentViewerOtherCasesTableModel_device(), 145);
|
||||
|
||||
private final String columnName;
|
||||
private final int columnWidth;
|
||||
@ -70,7 +70,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
}
|
||||
};
|
||||
|
||||
List<EamArtifact> eamArtifacts;
|
||||
List<CorrelationAttribute> eamArtifacts;
|
||||
|
||||
DataContentViewerOtherCasesTableModel() {
|
||||
eamArtifacts = new ArrayList<>();
|
||||
@ -127,8 +127,8 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
* @return value in the cell
|
||||
*/
|
||||
private Object mapValueById(int rowIdx, TableColumns colId) {
|
||||
EamArtifact eamArtifact = eamArtifacts.get(rowIdx);
|
||||
EamArtifactInstance eamArtifactInstance = eamArtifact.getInstances().get(0);
|
||||
CorrelationAttribute eamArtifact = eamArtifacts.get(rowIdx);
|
||||
CorrelationAttributeInstance eamArtifactInstance = eamArtifact.getInstances().get(0);
|
||||
String value = Bundle.DataContentViewerOtherCasesTableModel_noData();
|
||||
|
||||
switch (colId) {
|
||||
@ -180,13 +180,14 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
* @param eamArtifact central repository artifact to add to the
|
||||
* table
|
||||
*/
|
||||
public void addEamArtifact(EamArtifact eamArtifact) {
|
||||
public void addEamArtifact(CorrelationAttribute eamArtifact) {
|
||||
eamArtifacts.add(eamArtifact);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
public void clearTable() {
|
||||
eamArtifacts.clear();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,11 +47,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName());
|
||||
|
||||
protected final List<EamArtifact.Type> DEFAULT_CORRELATION_TYPES;
|
||||
protected final List<CorrelationAttribute.Type> DEFAULT_CORRELATION_TYPES;
|
||||
|
||||
private int bulkArtifactsCount;
|
||||
protected int bulkArtifactsThreshold;
|
||||
private final Map<String, Collection<EamArtifact>> bulkArtifacts;
|
||||
private final Map<String, Collection<CorrelationAttribute>> bulkArtifacts;
|
||||
private final List<String> badTags;
|
||||
|
||||
/**
|
||||
@ -64,7 +64,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
bulkArtifactsCount = 0;
|
||||
bulkArtifacts = new HashMap<>();
|
||||
|
||||
DEFAULT_CORRELATION_TYPES = EamArtifact.getDefaultCorrelationTypes();
|
||||
DEFAULT_CORRELATION_TYPES = CorrelationAttribute.getDefaultCorrelationTypes();
|
||||
DEFAULT_CORRELATION_TYPES.forEach((type) -> {
|
||||
bulkArtifacts.put(type.getDbTableName(), new ArrayList<>());
|
||||
});
|
||||
@ -423,7 +423,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param eamDataSource the data source to add
|
||||
*/
|
||||
@Override
|
||||
public void newDataSource(EamDataSource eamDataSource) throws EamDbException {
|
||||
public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@ -451,7 +451,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param eamDataSource the data source to update
|
||||
*/
|
||||
@Override
|
||||
public void updateDataSource(EamDataSource eamDataSource) throws EamDbException {
|
||||
public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@ -480,10 +480,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return The data source
|
||||
*/
|
||||
@Override
|
||||
public EamDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException {
|
||||
public CorrelationDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
EamDataSource eamDataSourceResult = null;
|
||||
CorrelationDataSource eamDataSourceResult = null;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -513,11 +513,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return list of data sources in the DB
|
||||
*/
|
||||
@Override
|
||||
public List<EamDataSource> getDataSources() throws EamDbException {
|
||||
public List<CorrelationDataSource> getDataSources() throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamDataSource> dataSources = new ArrayList<>();
|
||||
EamDataSource eamDataSourceResult;
|
||||
List<CorrelationDataSource> dataSources = new ArrayList<>();
|
||||
CorrelationDataSource eamDataSourceResult;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -548,12 +548,14 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param eamArtifact The artifact to add
|
||||
*/
|
||||
@Override
|
||||
public void addArtifact(EamArtifact eamArtifact) throws EamDbException {
|
||||
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifactInstance> eamInstances = eamArtifact.getInstances();
|
||||
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
|
||||
PreparedStatement preparedStatement = null;
|
||||
|
||||
|
||||
// @@@ We should cache the case and data source IDs in memory
|
||||
String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("INSERT INTO ");
|
||||
@ -564,7 +566,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql.toString());
|
||||
for (EamArtifactInstance eamInstance : eamInstances) {
|
||||
for (CorrelationAttributeInstance eamInstance : eamInstances) {
|
||||
if(! eamArtifact.getCorrelationValue().isEmpty()){
|
||||
preparedStatement.setString(1, eamInstance.getEamCase().getCaseUUID());
|
||||
preparedStatement.setString(2, eamInstance.getEamDataSource().getDeviceID());
|
||||
@ -597,12 +599,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return List of artifact instances for a given type/value
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifactInstance> artifactInstances = new ArrayList<>();
|
||||
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
||||
|
||||
EamArtifactInstance artifactInstance;
|
||||
CorrelationAttributeInstance artifactInstance;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -649,12 +651,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesByPath(EamArtifact.Type aType, String filePath) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifactInstance> artifactInstances = new ArrayList<>();
|
||||
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
||||
|
||||
EamArtifactInstance artifactInstance;
|
||||
CorrelationAttributeInstance artifactInstance;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -700,7 +702,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* ArtifactValue.
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
Long instanceCount = 0L;
|
||||
@ -730,21 +732,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return instanceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the ArtifactType and ArtifactValue from the given eamArtfact,
|
||||
* compute the ratio of: (The number of unique case_id/datasource_id tuples
|
||||
* where Type/Value is found) divided by (The total number of unique
|
||||
* case_id/datasource_id tuples in the database) expressed as a percentage.
|
||||
*
|
||||
* @param eamArtifact Artifact with artifactType and artifactValue to search
|
||||
* for
|
||||
*
|
||||
* @return Int between 0 and 100
|
||||
*/
|
||||
|
||||
@Override
|
||||
public int getCommonalityPercentageForTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value).doubleValue();
|
||||
Double uniqueCaseDataSourceTuples = getCountUniqueCaseDataSourceTuples().doubleValue();
|
||||
public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException {
|
||||
Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
|
||||
Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
|
||||
Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
|
||||
return commonalityPercentage.intValue();
|
||||
}
|
||||
@ -760,7 +752,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return Number of unique tuples
|
||||
*/
|
||||
@Override
|
||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
Long instanceCount = 0L;
|
||||
@ -792,41 +784,24 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return instanceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves number of unique caseDisplayName/dataSource tuples in the
|
||||
* database.
|
||||
*
|
||||
* @return Number of unique tuples
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Long getCountUniqueCaseDataSourceTuples() throws EamDbException {
|
||||
public Long getCountUniqueDataSources() throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
Long instanceCount = 0L;
|
||||
List<EamArtifact.Type> artifactTypes = getCorrelationTypes();
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT 0 ");
|
||||
|
||||
for (EamArtifact.Type type : artifactTypes) {
|
||||
String table_name = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
|
||||
sql.append("+ (SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM ");
|
||||
sql.append(table_name);
|
||||
sql.append(") AS ");
|
||||
sql.append(table_name);
|
||||
sql.append("_distinct_case_data_source_tuple) ");
|
||||
}
|
||||
String stmt = "SELECT count(*) FROM data_sources";
|
||||
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql.toString());
|
||||
preparedStatement = conn.prepareStatement(stmt);
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
resultSet.next();
|
||||
instanceCount = resultSet.getLong(1);
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples.", ex); // NON-NLS
|
||||
throw new EamDbException("Error counting data sources.", ex); // NON-NLS
|
||||
} finally {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement);
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
@ -852,7 +827,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
Connection conn = connect();
|
||||
|
||||
Long instanceCount = 0L;
|
||||
List<EamArtifact.Type> artifactTypes = getCorrelationTypes();
|
||||
List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -860,7 +835,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT 0 ");
|
||||
|
||||
for (EamArtifact.Type type : artifactTypes) {
|
||||
for (CorrelationAttribute.Type type : artifactTypes) {
|
||||
String table_name = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
|
||||
sql.append("+ (SELECT count(*) FROM ");
|
||||
@ -898,7 +873,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param eamArtifact The artifact to add
|
||||
*/
|
||||
@Override
|
||||
public void prepareBulkArtifact(EamArtifact eamArtifact) throws EamDbException {
|
||||
public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
|
||||
|
||||
synchronized (bulkArtifacts) {
|
||||
bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact);
|
||||
@ -923,7 +898,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
*/
|
||||
@Override
|
||||
public void bulkInsertArtifacts() throws EamDbException {
|
||||
List<EamArtifact.Type> artifactTypes = getCorrelationTypes();
|
||||
List<CorrelationAttribute.Type> artifactTypes = getDefinedCorrelationTypes();
|
||||
|
||||
Connection conn = connect();
|
||||
PreparedStatement bulkPs = null;
|
||||
@ -934,7 +909,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EamArtifact.Type type : artifactTypes) {
|
||||
for (CorrelationAttribute.Type type : artifactTypes) {
|
||||
|
||||
String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
StringBuilder sql = new StringBuilder();
|
||||
@ -947,11 +922,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
bulkPs = conn.prepareStatement(sql.toString());
|
||||
|
||||
Collection<EamArtifact> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
|
||||
for (EamArtifact eamArtifact : eamArtifacts) {
|
||||
List<EamArtifactInstance> eamInstances = eamArtifact.getInstances();
|
||||
Collection<CorrelationAttribute> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
|
||||
for (CorrelationAttribute eamArtifact : eamArtifacts) {
|
||||
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
|
||||
|
||||
for (EamArtifactInstance eamInstance : eamInstances) {
|
||||
for (CorrelationAttributeInstance eamInstance : eamInstances) {
|
||||
if(! eamArtifact.getCorrelationValue().isEmpty()){
|
||||
bulkPs.setString(1, eamInstance.getEamCase().getCaseUUID());
|
||||
bulkPs.setString(2, eamInstance.getEamDataSource().getDeviceID());
|
||||
@ -1068,15 +1043,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param FileKnown The status to change the artifact to
|
||||
*/
|
||||
@Override
|
||||
public void setArtifactInstanceKnownStatus(EamArtifact eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
if (1 != eamArtifact.getInstances().size()) {
|
||||
throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS
|
||||
}
|
||||
|
||||
List<EamArtifactInstance> eamInstances = eamArtifact.getInstances();
|
||||
EamArtifactInstance eamInstance = eamInstances.get(0);
|
||||
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
|
||||
CorrelationAttributeInstance eamInstance = eamInstances.get(0);
|
||||
|
||||
PreparedStatement preparedUpdate = null;
|
||||
PreparedStatement preparedQuery = null;
|
||||
@ -1160,12 +1135,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return List with 0 or more matching eamArtifact instances.
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifactInstance> artifactInstances = new ArrayList<>();
|
||||
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
||||
|
||||
EamArtifactInstance artifactInstance;
|
||||
CorrelationAttributeInstance artifactInstance;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@ -1210,7 +1185,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return Number of matching eamArtifacts
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
Long badInstances = 0L;
|
||||
@ -1254,7 +1229,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
Collection<String> caseNames = new LinkedHashSet<>();
|
||||
@ -1302,10 +1277,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @return Global known status of the artifact
|
||||
*/
|
||||
@Override
|
||||
public boolean isArtifactlKnownBadByReference(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public boolean isArtifactlKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
|
||||
// TEMP: Only support file correlation type
|
||||
if (aType.getId() != EamArtifact.FILES_TYPE_ID) {
|
||||
if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1521,7 +1496,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, EamArtifact.Type correlationType) throws EamDbException {
|
||||
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@ -1549,7 +1524,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, EamArtifact.Type contentType) throws EamDbException {
|
||||
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement bulkPs = null;
|
||||
@ -1596,7 +1571,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(EamArtifact.Type aType, String aValue) throws EamDbException {
|
||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>();
|
||||
@ -1632,7 +1607,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public int newCorrelationType(EamArtifact.Type newType) throws EamDbException {
|
||||
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@ -1673,7 +1648,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
resultSet = preparedStatementQuery.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
EamArtifact.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
|
||||
CorrelationAttribute.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
|
||||
typeId = correlationType.getId();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -1687,20 +1662,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of EamArtifact.Type's that will be used to correlate
|
||||
* artifacts.
|
||||
*
|
||||
* @return List of EamArtifact.Type's. If none are defined in the database,
|
||||
* the default list will be returned.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
|
||||
@Override
|
||||
public List<EamArtifact.Type> getCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getDefinedCorrelationTypes() throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifact.Type> aTypes = new ArrayList<>();
|
||||
List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT * FROM correlation_types";
|
||||
@ -1732,10 +1699,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifact.Type> getEnabledCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getEnabledCorrelationTypes() throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifact.Type> aTypes = new ArrayList<>();
|
||||
List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT * FROM correlation_types WHERE enabled=1";
|
||||
@ -1767,10 +1734,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifact.Type> getSupportedCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getSupportedCorrelationTypes() throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
List<EamArtifact.Type> aTypes = new ArrayList<>();
|
||||
List<CorrelationAttribute.Type> aTypes = new ArrayList<>();
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT * FROM correlation_types WHERE supported=1";
|
||||
@ -1800,7 +1767,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void updateCorrelationType(EamArtifact.Type aType) throws EamDbException {
|
||||
public void updateCorrelationType(CorrelationAttribute.Type aType) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@ -1834,10 +1801,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public EamArtifact.Type getCorrelationTypeById(int typeId) throws EamDbException {
|
||||
public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
EamArtifact.Type aType;
|
||||
CorrelationAttribute.Type aType;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT * FROM correlation_types WHERE id=?";
|
||||
@ -1899,12 +1866,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return eamCase;
|
||||
}
|
||||
|
||||
private EamDataSource getEamDataSourceFromResultSet(ResultSet resultSet) throws SQLException {
|
||||
private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet) throws SQLException {
|
||||
if (null == resultSet) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EamDataSource eamDataSource = new EamDataSource(
|
||||
CorrelationDataSource eamDataSource = new CorrelationDataSource(
|
||||
resultSet.getInt("id"),
|
||||
resultSet.getString("device_id"),
|
||||
resultSet.getString("name")
|
||||
@ -1913,12 +1880,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return eamDataSource;
|
||||
}
|
||||
|
||||
private EamArtifact.Type getCorrelationTypeFromResultSet(ResultSet resultSet) throws EamDbException, SQLException {
|
||||
private CorrelationAttribute.Type getCorrelationTypeFromResultSet(ResultSet resultSet) throws EamDbException, SQLException {
|
||||
if (null == resultSet) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EamArtifact.Type eamArtifactType = new EamArtifact.Type(
|
||||
CorrelationAttribute.Type eamArtifactType = new CorrelationAttribute.Type(
|
||||
resultSet.getInt("id"),
|
||||
resultSet.getString("display_name"),
|
||||
resultSet.getString("db_table_name"),
|
||||
@ -1939,17 +1906,17 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
*
|
||||
* @throws SQLException when an expected column name is not in the resultSet
|
||||
*/
|
||||
private EamArtifactInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException {
|
||||
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException {
|
||||
if (null == resultSet) {
|
||||
return null;
|
||||
}
|
||||
EamArtifactInstance eamArtifactInstance = new EamArtifactInstance(
|
||||
CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance(
|
||||
new EamCase(resultSet.getString("case_uid"), resultSet.getString("case_name")),
|
||||
new EamDataSource(resultSet.getString("device_id"), resultSet.getString("name")),
|
||||
new CorrelationDataSource(-1, resultSet.getString("device_id"), resultSet.getString("name")),
|
||||
resultSet.getString("file_path"),
|
||||
resultSet.getString("comment"),
|
||||
TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
|
||||
EamArtifactInstance.GlobalStatus.LOCAL
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
);
|
||||
|
||||
return eamArtifactInstance;
|
||||
|
@ -26,17 +26,18 @@ import java.util.regex.Pattern;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to store info about a specific artifact.
|
||||
* Represents a type and value pair that can be used for correlation.
|
||||
* CorrelationAttributeInstances store information about the actual
|
||||
* occurences of the attribute.
|
||||
*/
|
||||
public class EamArtifact implements Serializable {
|
||||
public class CorrelationAttribute implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String ID;
|
||||
private String correlationValue;
|
||||
private Type correlationType;
|
||||
private final List<EamArtifactInstance> artifactInstances;
|
||||
private final List<CorrelationAttributeInstance> artifactInstances;
|
||||
|
||||
// Type ID's for Default Correlation Types
|
||||
public static final int FILES_TYPE_ID = 0;
|
||||
@ -55,17 +56,17 @@ public class EamArtifact implements Serializable {
|
||||
"CorrelationType.EMAIL.displayName=Email Addresses",
|
||||
"CorrelationType.PHONE.displayName=Phone Numbers",
|
||||
"CorrelationType.USBID.displayName=USB Devices"})
|
||||
public static List<EamArtifact.Type> getDefaultCorrelationTypes() throws EamDbException {
|
||||
List<EamArtifact.Type> DEFAULT_CORRELATION_TYPES = new ArrayList<>();
|
||||
DEFAULT_CORRELATION_TYPES.add(new EamArtifact.Type(FILES_TYPE_ID, Bundle.CorrelationType_FILES_displayName(), "file", true, true)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new EamArtifact.Type(DOMAIN_TYPE_ID, Bundle.CorrelationType_DOMAIN_displayName(), "domain", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new EamArtifact.Type(EMAIL_TYPE_ID, Bundle.CorrelationType_EMAIL_displayName(), "email_address", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new EamArtifact.Type(PHONE_TYPE_ID, Bundle.CorrelationType_PHONE_displayName(), "phone_number", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new EamArtifact.Type(USBID_TYPE_ID, Bundle.CorrelationType_USBID_displayName(), "usb_devices", true, false)); // NON-NLS
|
||||
public static List<CorrelationAttribute.Type> getDefaultCorrelationTypes() throws EamDbException {
|
||||
List<CorrelationAttribute.Type> DEFAULT_CORRELATION_TYPES = new ArrayList<>();
|
||||
DEFAULT_CORRELATION_TYPES.add(new CorrelationAttribute.Type(FILES_TYPE_ID, Bundle.CorrelationType_FILES_displayName(), "file", true, true)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new CorrelationAttribute.Type(DOMAIN_TYPE_ID, Bundle.CorrelationType_DOMAIN_displayName(), "domain", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new CorrelationAttribute.Type(EMAIL_TYPE_ID, Bundle.CorrelationType_EMAIL_displayName(), "email_address", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new CorrelationAttribute.Type(PHONE_TYPE_ID, Bundle.CorrelationType_PHONE_displayName(), "phone_number", true, false)); // NON-NLS
|
||||
DEFAULT_CORRELATION_TYPES.add(new CorrelationAttribute.Type(USBID_TYPE_ID, Bundle.CorrelationType_USBID_displayName(), "usb_devices", true, false)); // NON-NLS
|
||||
return DEFAULT_CORRELATION_TYPES;
|
||||
}
|
||||
|
||||
public EamArtifact(Type correlationType, String correlationValue) {
|
||||
public CorrelationAttribute(Type correlationType, String correlationValue) {
|
||||
this.ID = "";
|
||||
this.correlationType = correlationType;
|
||||
// Lower-case all values to normalize and improve correlation hits, going forward make sure this makes sense for all correlation types
|
||||
@ -73,7 +74,7 @@ public class EamArtifact implements Serializable {
|
||||
this.artifactInstances = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Boolean equals(EamArtifact otherArtifact) {
|
||||
public Boolean equals(CorrelationAttribute otherArtifact) {
|
||||
return ((this.getID().equals(otherArtifact.getID()))
|
||||
&& (this.getCorrelationType().equals(otherArtifact.getCorrelationType()))
|
||||
&& (this.getCorrelationValue().equals(otherArtifact.getCorrelationValue()))
|
||||
@ -82,6 +83,8 @@ public class EamArtifact implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// NOTE: This string is currently being used in IngestEventsListener to detect if we have already seen
|
||||
// the value and type pair. Be careful if this method is changed.
|
||||
String result = this.getID()
|
||||
+ this.getCorrelationType().toString()
|
||||
+ this.getCorrelationValue();
|
||||
@ -136,14 +139,14 @@ public class EamArtifact implements Serializable {
|
||||
* @return the List of artifactInstances; empty list of none have been
|
||||
* added.
|
||||
*/
|
||||
public List<EamArtifactInstance> getInstances() {
|
||||
public List<CorrelationAttributeInstance> getInstances() {
|
||||
return new ArrayList<>(artifactInstances);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param artifactInstances the List of artifactInstances to set.
|
||||
*/
|
||||
public void setInstances(List<EamArtifactInstance> artifactInstances) {
|
||||
public void setInstances(List<CorrelationAttributeInstance> artifactInstances) {
|
||||
this.artifactInstances.clear();
|
||||
if (null != artifactInstances) {
|
||||
this.artifactInstances.addAll(artifactInstances);
|
||||
@ -153,7 +156,7 @@ public class EamArtifact implements Serializable {
|
||||
/**
|
||||
* @param instance the instance to add
|
||||
*/
|
||||
public void addInstance(EamArtifactInstance artifactInstance) {
|
||||
public void addInstance(CorrelationAttributeInstance artifactInstance) {
|
||||
this.artifactInstances.add(artifactInstance);
|
||||
}
|
||||
|
||||
@ -214,10 +217,10 @@ public class EamArtifact implements Serializable {
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
} else if (!(that instanceof EamArtifact.Type)) {
|
||||
} else if (!(that instanceof CorrelationAttribute.Type)) {
|
||||
return false;
|
||||
} else {
|
||||
return ((EamArtifact.Type) that).sameType(this);
|
||||
return ((CorrelationAttribute.Type) that).sameType(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,7 +232,7 @@ public class EamArtifact implements Serializable {
|
||||
*
|
||||
* @return true if it is the same type
|
||||
*/
|
||||
private boolean sameType(EamArtifact.Type that) {
|
||||
private boolean sameType(CorrelationAttribute.Type that) {
|
||||
return this.id == that.getId()
|
||||
&& Objects.equals(this.supported, that.isSupported())
|
||||
&& Objects.equals(this.enabled, that.isEnabled());
|
@ -24,7 +24,8 @@ import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to store info about a specific Artifact Instance.
|
||||
* Used to store details about a specific instance of a
|
||||
* CorrelationAttribute. Includes its data source, path, etc.
|
||||
*
|
||||
*/
|
||||
@Messages({"EamArtifactInstances.globalStatus.local=Local",
|
||||
@ -32,7 +33,7 @@ import org.sleuthkit.datamodel.TskData;
|
||||
"EamArtifactInstances.knownStatus.bad=Bad",
|
||||
"EamArtifactInstances.knownStatus.known=Known",
|
||||
"EamArtifactInstances.knownStatus.unknown=Unknown"})
|
||||
public class EamArtifactInstance implements Serializable {
|
||||
public class CorrelationAttributeInstance implements Serializable {
|
||||
|
||||
public enum GlobalStatus {
|
||||
LOCAL(Bundle.EamArtifactInstances_globalStatus_local()),
|
||||
@ -54,39 +55,39 @@ public class EamArtifactInstance implements Serializable {
|
||||
|
||||
private String ID;
|
||||
private EamCase eamCase;
|
||||
private EamDataSource eamDataSource;
|
||||
private CorrelationDataSource eamDataSource;
|
||||
private String filePath;
|
||||
private String comment;
|
||||
private TskData.FileKnown knownStatus;
|
||||
private GlobalStatus globalStatus;
|
||||
|
||||
public EamArtifactInstance(
|
||||
public CorrelationAttributeInstance(
|
||||
EamCase eamCase,
|
||||
EamDataSource eamDataSource
|
||||
CorrelationDataSource eamDataSource
|
||||
) {
|
||||
this("", eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
}
|
||||
|
||||
public EamArtifactInstance(
|
||||
public CorrelationAttributeInstance(
|
||||
EamCase eamCase,
|
||||
EamDataSource eamDataSource,
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath
|
||||
) {
|
||||
this("", eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
}
|
||||
|
||||
public EamArtifactInstance(
|
||||
public CorrelationAttributeInstance(
|
||||
EamCase eamCase,
|
||||
EamDataSource eamDataSource,
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath,
|
||||
String comment
|
||||
) {
|
||||
this("", eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
}
|
||||
|
||||
public EamArtifactInstance(
|
||||
public CorrelationAttributeInstance(
|
||||
EamCase eamCase,
|
||||
EamDataSource eamDataSource,
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath,
|
||||
String comment,
|
||||
TskData.FileKnown knownStatus,
|
||||
@ -95,10 +96,10 @@ public class EamArtifactInstance implements Serializable {
|
||||
this("", eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus);
|
||||
}
|
||||
|
||||
public EamArtifactInstance(
|
||||
public CorrelationAttributeInstance(
|
||||
String ID,
|
||||
EamCase eamCase,
|
||||
EamDataSource eamDataSource,
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath,
|
||||
String comment,
|
||||
TskData.FileKnown knownStatus,
|
||||
@ -114,7 +115,7 @@ public class EamArtifactInstance implements Serializable {
|
||||
this.globalStatus = globalStatus;
|
||||
}
|
||||
|
||||
public Boolean equals(EamArtifactInstance otherInstance) {
|
||||
public Boolean equals(CorrelationAttributeInstance otherInstance) {
|
||||
return ((this.getID().equals(otherInstance.getID()))
|
||||
&& (this.getEamCase().equals(otherInstance.getEamCase()))
|
||||
&& (this.getEamDataSource().equals(otherInstance.getEamDataSource()))
|
||||
@ -166,14 +167,14 @@ public class EamArtifactInstance implements Serializable {
|
||||
/**
|
||||
* @return the eamDataSource
|
||||
*/
|
||||
public EamDataSource getEamDataSource() {
|
||||
public CorrelationDataSource getEamDataSource() {
|
||||
return eamDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eamDataSource the eamDataSource to set
|
||||
*/
|
||||
public void setEamDataSource(EamDataSource eamDataSource) {
|
||||
public void setEamDataSource(CorrelationDataSource eamDataSource) {
|
||||
this.eamDataSource = eamDataSource;
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-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.centralrepository.datamodel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskDataException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Stores information about a Data Source in the correlation engine
|
||||
*
|
||||
*/
|
||||
public class CorrelationDataSource implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final int dataSourceId; //< Id in the central repo
|
||||
private final String deviceID;
|
||||
private final String name;
|
||||
|
||||
|
||||
CorrelationDataSource(int dataSourceId,
|
||||
String deviceID,
|
||||
String name) {
|
||||
this.dataSourceId = dataSourceId;
|
||||
this.deviceID = deviceID;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CorrelationDataSource object from a TSK Content object.
|
||||
*
|
||||
* @param dataSource
|
||||
* @return
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public static CorrelationDataSource fromTSKDataSource(Content dataSource) throws EamDbException {
|
||||
Case curCase;
|
||||
try {
|
||||
curCase = Case.getCurrentCase();
|
||||
} catch (IllegalStateException ex) {
|
||||
throw new EamDbException("Autopsy case is closed");
|
||||
}
|
||||
String deviceId;
|
||||
try {
|
||||
deviceId = curCase.getSleuthkitCase().getDataSource(dataSource.getId()).getDeviceId();
|
||||
} catch (TskDataException | TskCoreException ex) {
|
||||
throw new EamDbException("Error getting data source info: " + ex.getMessage());
|
||||
}
|
||||
return new CorrelationDataSource(-1, deviceId, dataSource.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("(");
|
||||
str.append("ID=").append(Integer.toString(getDataSourceID()));
|
||||
str.append(",deviceID=").append(getDeviceID());
|
||||
str.append(",name=").append(getName());
|
||||
str.append(")");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ID
|
||||
*/
|
||||
public int getDataSourceID() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deviceID
|
||||
*/
|
||||
public String getDeviceID() {
|
||||
return deviceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -55,53 +56,65 @@ public class EamArtifactUtil {
|
||||
* null.
|
||||
*
|
||||
* @param bbArtifact BlackboardArtifact to examine
|
||||
* @param addInstanceDetails If true, add instance details from bbArtifact into the returned structure
|
||||
* @param checkEnabled If true, only create a CorrelationAttribute if it is enabled
|
||||
|
||||
* @return List of EamArtifacts
|
||||
*/
|
||||
public static List<EamArtifact> fromBlackboardArtifact(BlackboardArtifact bbArtifact,
|
||||
boolean includeInstances,
|
||||
List<EamArtifact.Type> artifactTypes,
|
||||
boolean checkEnabled) {
|
||||
public static List<CorrelationAttribute> getCorrelationAttributeFromBlackboardArtifact(BlackboardArtifact bbArtifact,
|
||||
boolean addInstanceDetails, boolean checkEnabled) {
|
||||
|
||||
List<CorrelationAttribute> eamArtifacts = new ArrayList<>();
|
||||
|
||||
List<EamArtifact> eamArtifacts = new ArrayList<>();
|
||||
|
||||
for (EamArtifact.Type aType : artifactTypes) {
|
||||
if ((checkEnabled && aType.isEnabled()) || !checkEnabled) {
|
||||
EamArtifact eamArtifact = getTypeFromBlackboardArtifact(aType, bbArtifact);
|
||||
if (eamArtifact != null) {
|
||||
eamArtifacts.add(eamArtifact);
|
||||
try {
|
||||
// Cycle through the types and see if there is a correlation attribute that works
|
||||
// for the given blackboard artifact
|
||||
//
|
||||
// @@@ This seems ineffecient. Instead of cycling based on correlation type, we should just
|
||||
// have switch based on artifact type
|
||||
for (CorrelationAttribute.Type aType : EamDb.getInstance().getDefinedCorrelationTypes()) {
|
||||
if ((checkEnabled && aType.isEnabled()) || !checkEnabled) {
|
||||
CorrelationAttribute eamArtifact = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(aType, bbArtifact);
|
||||
if (eamArtifact != null) {
|
||||
eamArtifacts.add(eamArtifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting defined correlation types.", ex); // NON-NLS
|
||||
return eamArtifacts;
|
||||
}
|
||||
|
||||
if (!eamArtifacts.isEmpty() && includeInstances) {
|
||||
// if they asked for it, add the instance details associated with this occurance.
|
||||
if (!eamArtifacts.isEmpty() && addInstanceDetails) {
|
||||
try {
|
||||
AbstractFile af = Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
|
||||
if (null == af) {
|
||||
return null;
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
AbstractFile bbSourceFile = currentCase.getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
|
||||
if (null == bbSourceFile) {
|
||||
//@@@ Log this
|
||||
return eamArtifacts;
|
||||
}
|
||||
|
||||
String deviceId = "";
|
||||
try {
|
||||
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
|
||||
} catch (TskCoreException | TskDataException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error, failed to get deviceID or data source from current case.", ex);
|
||||
}
|
||||
|
||||
EamArtifactInstance eamInstance = new EamArtifactInstance(
|
||||
new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()),
|
||||
new EamDataSource(deviceId, af.getDataSource().getName()),
|
||||
af.getParentPath() + af.getName(),
|
||||
// make an instance for the BB source file
|
||||
CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance(
|
||||
new EamCase(currentCase.getName(), currentCase.getDisplayName()),
|
||||
CorrelationDataSource.fromTSKDataSource(bbSourceFile.getDataSource()),
|
||||
bbSourceFile.getParentPath() + bbSourceFile.getName(),
|
||||
"",
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
EamArtifactInstance.GlobalStatus.LOCAL
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
);
|
||||
|
||||
for (EamArtifact eamArtifact : eamArtifacts) {
|
||||
// add the instance details
|
||||
for (CorrelationAttribute eamArtifact : eamArtifacts) {
|
||||
eamArtifact.addInstance(eamInstance);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
} catch (TskCoreException | EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error creating artifact instance.", ex); // NON-NLS
|
||||
return null;
|
||||
return eamArtifacts;
|
||||
} catch (IllegalStateException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Case is closed.", ex); // NON-NLS
|
||||
return eamArtifacts;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,16 +122,16 @@ public class EamArtifactUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a blackboard artifact to an EamArtifact.
|
||||
* Returns null if the converted artifact does not contain valid
|
||||
* correlation data.
|
||||
* Create an EamArtifact of type correlationType if one can be generated
|
||||
* based on the data in the blackboard artifact.
|
||||
*
|
||||
* @param aType The Central Repository artifact type to create
|
||||
* @param bbArtifact The blackboard artifact to convert
|
||||
* @param correlationType The Central Repository artifact type to create
|
||||
* @param bbArtifact The blackboard artifact to pull data from
|
||||
*
|
||||
* @return the new EamArtifact, or null if one was not created
|
||||
* @return the new EamArtifact, or null if one was not created because bbArtifact
|
||||
* did not contain the needed data
|
||||
*/
|
||||
public static EamArtifact getTypeFromBlackboardArtifact(EamArtifact.Type aType, BlackboardArtifact bbArtifact) {
|
||||
private static CorrelationAttribute getCorrelationAttributeFromBlackboardArtifact(CorrelationAttribute.Type correlationType, BlackboardArtifact bbArtifact) {
|
||||
String value = null;
|
||||
int artifactTypeID = bbArtifact.getArtifactTypeID();
|
||||
|
||||
@ -128,10 +141,10 @@ public class EamArtifactUtil {
|
||||
BlackboardAttribute attribute = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||
if (attribute != null) {
|
||||
BlackboardArtifact associatedArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(attribute.getValueLong());
|
||||
return getTypeFromBlackboardArtifact(aType, associatedArtifact);
|
||||
return EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(correlationType, associatedArtifact);
|
||||
}
|
||||
|
||||
} else if (aType.getId() == EamArtifact.EMAIL_TYPE_ID
|
||||
} else if (correlationType.getId() == CorrelationAttribute.EMAIL_TYPE_ID
|
||||
&& BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() == artifactTypeID) {
|
||||
|
||||
BlackboardAttribute setNameAttr = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
|
||||
@ -139,7 +152,7 @@ public class EamArtifactUtil {
|
||||
&& EamArtifactUtil.getEmailAddressAttrString().equals(setNameAttr.getValueString())) {
|
||||
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD)).getValueString();
|
||||
}
|
||||
} else if (aType.getId() == EamArtifact.DOMAIN_TYPE_ID
|
||||
} else if (correlationType.getId() == CorrelationAttribute.DOMAIN_TYPE_ID
|
||||
&& (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() == artifactTypeID
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() == artifactTypeID
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifactTypeID
|
||||
@ -147,7 +160,7 @@ public class EamArtifactUtil {
|
||||
|
||||
// Lower-case this to normalize domains
|
||||
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN)).getValueString();
|
||||
} else if (aType.getId() == EamArtifact.PHONE_TYPE_ID
|
||||
} else if (correlationType.getId() == CorrelationAttribute.PHONE_TYPE_ID
|
||||
&& (BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID() == artifactTypeID
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() == artifactTypeID
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifactTypeID)) {
|
||||
@ -176,7 +189,7 @@ public class EamArtifactUtil {
|
||||
}
|
||||
}
|
||||
|
||||
} else if (aType.getId() == EamArtifact.USBID_TYPE_ID
|
||||
} else if (correlationType.getId() == CorrelationAttribute.USBID_TYPE_ID
|
||||
&& BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID() == artifactTypeID) {
|
||||
|
||||
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)).getValueString();
|
||||
@ -188,7 +201,7 @@ public class EamArtifactUtil {
|
||||
}
|
||||
|
||||
if (null != value) {
|
||||
return new EamArtifact(aType, value);
|
||||
return new CorrelationAttribute(correlationType, value);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -196,15 +209,19 @@ public class EamArtifactUtil {
|
||||
|
||||
/**
|
||||
* Create an EamArtifact from the given Content.
|
||||
* Will return null if an artifact can not be created. Does not
|
||||
* add the artifact to the database.
|
||||
* Will return null if an artifact can not be created - this is not
|
||||
* necessarily an error case, it just means an artifact can't be made.
|
||||
* If creation fails due to an error (and not that the file is the wrong type
|
||||
* or it has no hash), the error will be logged before returning.
|
||||
*
|
||||
* Does not add the artifact to the database.
|
||||
*
|
||||
* @param content The content object
|
||||
* @param knownStatus Unknown, notable, or known
|
||||
* @param comment The comment for the new artifact (generally used for a tag comment)
|
||||
* @return The new EamArtifact or null if creation failed
|
||||
*/
|
||||
public static EamArtifact getEamArtifactFromContent(Content content, TskData.FileKnown knownStatus, String comment){
|
||||
public static CorrelationAttribute getEamArtifactFromContent(Content content, TskData.FileKnown knownStatus, String comment){
|
||||
|
||||
if(! (content instanceof AbstractFile)){
|
||||
return null;
|
||||
@ -220,45 +237,29 @@ public class EamArtifactUtil {
|
||||
|| (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String dsName;
|
||||
try {
|
||||
dsName = af.getDataSource().getName();
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error, unable to get name of data source from abstract file.", ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// We need a hash to make the artifact
|
||||
String md5 = af.getMd5Hash();
|
||||
if (md5 == null || md5.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String deviceId;
|
||||
try {
|
||||
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
|
||||
} catch (TskCoreException | TskDataException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error, failed to get deviceID or data source from current case.", ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
EamArtifact eamArtifact;
|
||||
CorrelationAttribute eamArtifact;
|
||||
try {
|
||||
EamArtifact.Type filesType = EamDb.getInstance().getCorrelationTypeById(EamArtifact.FILES_TYPE_ID);
|
||||
eamArtifact = new EamArtifact(filesType, af.getMd5Hash());
|
||||
EamArtifactInstance cei = new EamArtifactInstance(
|
||||
CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID);
|
||||
eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash());
|
||||
CorrelationAttributeInstance cei = new CorrelationAttributeInstance(
|
||||
new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()),
|
||||
new EamDataSource(deviceId, dsName),
|
||||
CorrelationDataSource.fromTSKDataSource(af.getDataSource()),
|
||||
af.getParentPath() + af.getName(),
|
||||
comment,
|
||||
TskData.FileKnown.BAD,
|
||||
EamArtifactInstance.GlobalStatus.LOCAL
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
);
|
||||
eamArtifact.addInstance(cei);
|
||||
return eamArtifact;
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error, unable to get FILES correlation type.", ex);
|
||||
} catch (TskCoreException | EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error making correlation attribute.", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-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.centralrepository.datamodel;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to store info about a case.
|
||||
*
|
||||
*/
|
||||
public class EamDataSource implements Serializable {
|
||||
|
||||
private static long serialVersionUID = 1L;
|
||||
|
||||
private int ID;
|
||||
private String deviceID;
|
||||
private String name;
|
||||
|
||||
public EamDataSource(String deviceID, String name) {
|
||||
this(-1, deviceID, name);
|
||||
}
|
||||
|
||||
public EamDataSource(int ID,
|
||||
String deviceID,
|
||||
String name) {
|
||||
this.ID = ID;
|
||||
this.deviceID = deviceID;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("(");
|
||||
str.append("ID=").append(Integer.toString(getID()));
|
||||
str.append(",deviceID=").append(getDeviceID());
|
||||
str.append(",name=").append(getName());
|
||||
str.append(")");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ID
|
||||
*/
|
||||
public int getID() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ID the ID to set
|
||||
*/
|
||||
public void setID(int ID) {
|
||||
this.ID = ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deviceID
|
||||
*/
|
||||
public String getDeviceID() {
|
||||
return deviceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deviceID the deviceID to set
|
||||
*/
|
||||
public void setDeviceID(String deviceID) {
|
||||
this.deviceID = deviceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
@ -184,14 +184,14 @@ public interface EamDb {
|
||||
*
|
||||
* @param eamDataSource the data source to add
|
||||
*/
|
||||
void newDataSource(EamDataSource eamDataSource) throws EamDbException;
|
||||
void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Updates a Data Source in the database
|
||||
*
|
||||
* @param eamDataSource the data source to update
|
||||
*/
|
||||
void updateDataSource(EamDataSource eamDataSource) throws EamDbException;
|
||||
void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves Data Source details based on data source device ID
|
||||
@ -200,14 +200,14 @@ public interface EamDb {
|
||||
*
|
||||
* @return The data source
|
||||
*/
|
||||
EamDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException;
|
||||
CorrelationDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves data sources that are in DB
|
||||
*
|
||||
* @return List of data sources
|
||||
*/
|
||||
List<EamDataSource> getDataSources() throws EamDbException;
|
||||
List<CorrelationDataSource> getDataSources() throws EamDbException;
|
||||
|
||||
/**
|
||||
* Inserts new Artifact(s) into the database. Should add associated Case and
|
||||
@ -215,7 +215,7 @@ public interface EamDb {
|
||||
*
|
||||
* @param eamArtifact The artifact to add
|
||||
*/
|
||||
void addArtifact(EamArtifact eamArtifact) throws EamDbException;
|
||||
void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves eamArtifact instances from the database that are associated
|
||||
@ -226,7 +226,7 @@ public interface EamDb {
|
||||
*
|
||||
* @return List of artifact instances for a given type/value
|
||||
*/
|
||||
List<EamArtifactInstance> getArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves eamArtifact instances from the database that are associated
|
||||
@ -239,7 +239,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
List<EamArtifactInstance> getArtifactInstancesByPath(EamArtifact.Type aType, String filePath) throws EamDbException;
|
||||
List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves number of artifact instances in the database that are
|
||||
@ -251,20 +251,16 @@ public interface EamDb {
|
||||
* @return Number of artifact instances having ArtifactType and
|
||||
* ArtifactValue.
|
||||
*/
|
||||
Long getCountArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Using the ArtifactType and ArtifactValue from the given eamArtfact,
|
||||
* compute the ratio of: (The number of unique case_id/datasource_id tuples
|
||||
* where Type/Value is found) divided by (The total number of unique
|
||||
* case_id/datasource_id tuples in the database) expressed as a percentage.
|
||||
* Calculate the percentage of data sources that have this attribute value.
|
||||
*
|
||||
* @param aType EamArtifact.Type to search for
|
||||
* @param value Value to search for
|
||||
* @param corAttr Attribute type and value to get data about
|
||||
*
|
||||
* @return Int between 0 and 100
|
||||
*/
|
||||
int getCommonalityPercentageForTypeValue(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves number of unique caseDisplayName / dataSource tuples in the
|
||||
@ -276,15 +272,14 @@ public interface EamDb {
|
||||
*
|
||||
* @return Number of unique tuples
|
||||
*/
|
||||
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves number of unique caseDisplayName/dataSource tuples in the
|
||||
* database.
|
||||
* Retrieves number of data sources in the database.
|
||||
*
|
||||
* @return Number of unique tuples
|
||||
* @return Number of unique data sources
|
||||
*/
|
||||
Long getCountUniqueCaseDataSourceTuples() throws EamDbException;
|
||||
Long getCountUniqueDataSources() throws EamDbException;
|
||||
|
||||
/**
|
||||
* Retrieves number of eamArtifact instances in the database that are
|
||||
@ -306,7 +301,7 @@ public interface EamDb {
|
||||
*
|
||||
* @param eamArtifact The artifact to add
|
||||
*/
|
||||
void prepareBulkArtifact(EamArtifact eamArtifact) throws EamDbException;
|
||||
void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Executes a bulk insert of the eamArtifacts added from the
|
||||
@ -326,7 +321,7 @@ public interface EamDb {
|
||||
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
|
||||
* @param FileKnown The status to change the artifact to
|
||||
*/
|
||||
void setArtifactInstanceKnownStatus(EamArtifact eamArtifact, TskData.FileKnown knownStatus) throws EamDbException;
|
||||
void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Gets list of matching eamArtifact instances that have knownStatus =
|
||||
@ -337,7 +332,7 @@ public interface EamDb {
|
||||
*
|
||||
* @return List with 0 or more matching eamArtifact instances.
|
||||
*/
|
||||
List<EamArtifactInstance> getArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Count matching eamArtifacts instances that have knownStatus = "Bad".
|
||||
@ -347,7 +342,7 @@ public interface EamDb {
|
||||
*
|
||||
* @return Number of matching eamArtifacts
|
||||
*/
|
||||
Long getCountArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Gets list of distinct case display names, where each case has 1+ Artifact
|
||||
@ -361,7 +356,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
List<String> getListCasesHavingArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Is the artifact known as bad according to the reference entries?
|
||||
@ -371,7 +366,7 @@ public interface EamDb {
|
||||
*
|
||||
* @return Global known status of the artifact
|
||||
*/
|
||||
boolean isArtifactlKnownBadByReference(EamArtifact.Type aType, String value) throws EamDbException;
|
||||
boolean isArtifactlKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Add a new organization
|
||||
@ -433,7 +428,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, EamArtifact.Type correlationType) throws EamDbException;
|
||||
void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Add a new global file instance to the bulk collection
|
||||
@ -452,7 +447,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, EamArtifact.Type contentType) throws EamDbException;
|
||||
void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Get all reference entries having a given correlation type and value
|
||||
@ -464,7 +459,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(EamArtifact.Type aType, String aValue) throws EamDbException;
|
||||
List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Add a new EamArtifact.Type to the db.
|
||||
@ -475,18 +470,18 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public int newCorrelationType(EamArtifact.Type newType) throws EamDbException;
|
||||
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Get the list of EamArtifact.Type's that will be used to correlate
|
||||
* artifacts.
|
||||
* Get the list of EamArtifact.Type's that are defined in the DB and can be
|
||||
* used to correlate artifacts.
|
||||
*
|
||||
* @return List of EamArtifact.Type's. If none are defined in the database,
|
||||
* the default list will be returned.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public List<EamArtifact.Type> getCorrelationTypes() throws EamDbException;
|
||||
public List<CorrelationAttribute.Type> getDefinedCorrelationTypes() throws EamDbException;
|
||||
|
||||
/**
|
||||
* Get the list of enabled EamArtifact.Type's that will be used to correlate
|
||||
@ -497,7 +492,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public List<EamArtifact.Type> getEnabledCorrelationTypes() throws EamDbException;
|
||||
public List<CorrelationAttribute.Type> getEnabledCorrelationTypes() throws EamDbException;
|
||||
|
||||
/**
|
||||
* Get the list of supported EamArtifact.Type's that can be used to
|
||||
@ -508,7 +503,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public List<EamArtifact.Type> getSupportedCorrelationTypes() throws EamDbException;
|
||||
public List<CorrelationAttribute.Type> getSupportedCorrelationTypes() throws EamDbException;
|
||||
|
||||
/**
|
||||
* Update a EamArtifact.Type.
|
||||
@ -517,7 +512,7 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public void updateCorrelationType(EamArtifact.Type aType) throws EamDbException;
|
||||
public void updateCorrelationType(CorrelationAttribute.Type aType) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Get the EamArtifact.Type that has the given Type.Id.
|
||||
@ -528,5 +523,5 @@ public interface EamDb {
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public EamArtifact.Type getCorrelationTypeById(int typeId) throws EamDbException;
|
||||
public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException;
|
||||
}
|
||||
|
@ -101,9 +101,9 @@ public class EamDbUtil {
|
||||
String sql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
|
||||
|
||||
try {
|
||||
List<EamArtifact.Type> DEFAULT_CORRELATION_TYPES = EamArtifact.getDefaultCorrelationTypes();
|
||||
List<CorrelationAttribute.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttribute.getDefaultCorrelationTypes();
|
||||
preparedStatement = conn.prepareStatement(sql);
|
||||
for (EamArtifact.Type newType : DEFAULT_CORRELATION_TYPES) {
|
||||
for (CorrelationAttribute.Type newType : DEFAULT_CORRELATION_TYPES) {
|
||||
preparedStatement.setInt(1, newType.getId());
|
||||
preparedStatement.setString(2, newType.getDisplayName());
|
||||
preparedStatement.setString(3, newType.getDbTableName());
|
||||
@ -230,7 +230,7 @@ public class EamDbUtil {
|
||||
*
|
||||
* @return Instance table name for this Type.
|
||||
*/
|
||||
public static String correlationTypeToInstanceTableName(EamArtifact.Type type) {
|
||||
public static String correlationTypeToInstanceTableName(CorrelationAttribute.Type type) {
|
||||
return type.getDbTableName() + "_instances";
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public class EamDbUtil {
|
||||
*
|
||||
* @return Reference table name for this Type.
|
||||
*/
|
||||
public static String correlationTypeToReferenceTableName(EamArtifact.Type type) {
|
||||
public static String correlationTypeToReferenceTableName(CorrelationAttribute.Type type) {
|
||||
return "reference_" + type.getDbTableName();
|
||||
}
|
||||
|
||||
|
@ -112,10 +112,10 @@ public class PostgresEamDb extends AbstractSqlEamDb {
|
||||
|
||||
String instancesTemplate = "TRUNCATE TABLE %s_instances RESTART IDENTITY CASCADE";
|
||||
String referencesTemplate = "TRUNCATE TABLE reference_%s RESTART IDENTITY CASCADE";
|
||||
for (EamArtifact.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
for (CorrelationAttribute.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
dropContent.executeUpdate(String.format(instancesTemplate, type.getDbTableName()));
|
||||
// FUTURE: support other reference types
|
||||
if (type.getId() == EamArtifact.FILES_TYPE_ID) {
|
||||
if (type.getId() == CorrelationAttribute.FILES_TYPE_ID) {
|
||||
dropContent.executeUpdate(String.format(referencesTemplate, type.getDbTableName()));
|
||||
}
|
||||
}
|
||||
|
@ -455,11 +455,11 @@ public final class PostgresEamDbSettings {
|
||||
stmt.execute(createDbInfoTable.toString());
|
||||
|
||||
// Create a separate instance and reference table for each correlation type
|
||||
List<EamArtifact.Type> DEFAULT_CORRELATION_TYPES = EamArtifact.getDefaultCorrelationTypes();
|
||||
List<CorrelationAttribute.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttribute.getDefaultCorrelationTypes();
|
||||
|
||||
String reference_type_dbname;
|
||||
String instance_type_dbname;
|
||||
for (EamArtifact.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
for (CorrelationAttribute.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
reference_type_dbname = EamDbUtil.correlationTypeToReferenceTableName(type);
|
||||
instance_type_dbname = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
|
||||
@ -470,7 +470,7 @@ public final class PostgresEamDbSettings {
|
||||
stmt.execute(String.format(instancesIdx4, instance_type_dbname, instance_type_dbname));
|
||||
|
||||
// FUTURE: allow more than the FILES type
|
||||
if (type.getId() == EamArtifact.FILES_TYPE_ID) {
|
||||
if (type.getId() == CorrelationAttribute.FILES_TYPE_ID) {
|
||||
stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname));
|
||||
stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname));
|
||||
stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname));
|
||||
|
@ -123,10 +123,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
|
||||
String instancesTemplate = "DELETE FROM %s_instances";
|
||||
String referencesTemplate = "DELETE FROM global_files";
|
||||
for (EamArtifact.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
for (CorrelationAttribute.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
dropContent.executeUpdate(String.format(instancesTemplate, type.getDbTableName()));
|
||||
// FUTURE: support other reference types
|
||||
if (type.getId() == EamArtifact.FILES_TYPE_ID) {
|
||||
if (type.getId() == CorrelationAttribute.FILES_TYPE_ID) {
|
||||
dropContent.executeUpdate(String.format(referencesTemplate, type.getDbTableName()));
|
||||
}
|
||||
}
|
||||
@ -350,7 +350,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @param eamDataSource the data source to add
|
||||
*/
|
||||
@Override
|
||||
public void newDataSource(EamDataSource eamDataSource) throws EamDbException {
|
||||
public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.newDataSource(eamDataSource);
|
||||
@ -365,7 +365,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @param eamDataSource the data source to update
|
||||
*/
|
||||
@Override
|
||||
public void updateDataSource(EamDataSource eamDataSource) throws EamDbException {
|
||||
public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.updateDataSource(eamDataSource);
|
||||
@ -382,7 +382,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return The data source
|
||||
*/
|
||||
@Override
|
||||
public EamDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException {
|
||||
public CorrelationDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getDataSourceDetails(dataSourceDeviceId);
|
||||
@ -397,7 +397,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return list of data sources in the DB
|
||||
*/
|
||||
@Override
|
||||
public List<EamDataSource> getDataSources() throws EamDbException {
|
||||
public List<CorrelationDataSource> getDataSources() throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getDataSources();
|
||||
@ -413,7 +413,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @param eamArtifact The artifact to add
|
||||
*/
|
||||
@Override
|
||||
public void addArtifact(EamArtifact eamArtifact) throws EamDbException {
|
||||
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.addArtifact(eamArtifact);
|
||||
@ -431,7 +431,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return List of artifact instances for a given type/value
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getArtifactInstancesByTypeValue(aType, value);
|
||||
@ -452,7 +452,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesByPath(EamArtifact.Type aType, String filePath) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getArtifactInstancesByPath(aType, filePath);
|
||||
@ -472,7 +472,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* ArtifactValue.
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesByTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCountArtifactInstancesByTypeValue(aType, value);
|
||||
@ -481,22 +481,11 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the ArtifactType and ArtifactValue from the given eamArtfact,
|
||||
* compute the ratio of: (The number of unique case_id/datasource_id tuples
|
||||
* where Type/Value is found) divided by (The total number of unique
|
||||
* case_id/datasource_id tuples in the database) expressed as a percentage.
|
||||
*
|
||||
* @param eamArtifact Artifact with artifactType and artifactValue to search
|
||||
* for
|
||||
*
|
||||
* @return Int between 0 and 100
|
||||
*/
|
||||
@Override
|
||||
public int getCommonalityPercentageForTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCommonalityPercentageForTypeValue(aType, value);
|
||||
return super.getFrequencyPercentage(corAttr);
|
||||
} finally {
|
||||
releaseSharedLock();
|
||||
}
|
||||
@ -513,7 +502,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return Number of unique tuples
|
||||
*/
|
||||
@Override
|
||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
|
||||
@ -522,17 +511,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves number of unique caseDisplayName/dataSource tuples in the
|
||||
* database.
|
||||
*
|
||||
* @return Number of unique tuples
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Long getCountUniqueCaseDataSourceTuples() throws EamDbException {
|
||||
public Long getCountUniqueDataSources() throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCountUniqueCaseDataSourceTuples();
|
||||
return super.getCountUniqueDataSources();
|
||||
} finally {
|
||||
releaseSharedLock();
|
||||
}
|
||||
@ -593,7 +577,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
|
||||
*/
|
||||
@Override
|
||||
public void setArtifactInstanceKnownStatus(EamArtifact eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.setArtifactInstanceKnownStatus(eamArtifact, knownStatus);
|
||||
@ -612,7 +596,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return List with 0 or more matching eamArtifact instances.
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifactInstance> getArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getArtifactInstancesKnownBad(aType, value);
|
||||
@ -630,7 +614,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return Number of matching eamArtifacts
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCountArtifactInstancesKnownBad(aType, value);
|
||||
@ -652,7 +636,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
|
||||
@ -670,7 +654,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @return Global known status of the artifact
|
||||
*/
|
||||
@Override
|
||||
public boolean isArtifactlKnownBadByReference(EamArtifact.Type aType, String value) throws EamDbException {
|
||||
public boolean isArtifactlKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.isArtifactlKnownBadByReference(aType, value);
|
||||
@ -780,7 +764,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, EamArtifact.Type correlationType) throws EamDbException {
|
||||
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.addReferenceInstance(eamGlobalFileInstance, correlationType);
|
||||
@ -795,7 +779,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, EamArtifact.Type contentType) throws EamDbException {
|
||||
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.bulkInsertReferenceTypeEntries(globalInstances, contentType);
|
||||
@ -815,7 +799,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(EamArtifact.Type aType, String aValue) throws EamDbException {
|
||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getReferenceInstancesByTypeValue(aType, aValue);
|
||||
@ -834,7 +818,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public int newCorrelationType(EamArtifact.Type newType) throws EamDbException {
|
||||
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
return super.newCorrelationType(newType);
|
||||
@ -853,10 +837,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifact.Type> getCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getDefinedCorrelationTypes() throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCorrelationTypes();
|
||||
return super.getDefinedCorrelationTypes();
|
||||
} finally {
|
||||
releaseSharedLock();
|
||||
}
|
||||
@ -872,7 +856,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifact.Type> getEnabledCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getEnabledCorrelationTypes() throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getEnabledCorrelationTypes();
|
||||
@ -891,7 +875,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamArtifact.Type> getSupportedCorrelationTypes() throws EamDbException {
|
||||
public List<CorrelationAttribute.Type> getSupportedCorrelationTypes() throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getSupportedCorrelationTypes();
|
||||
@ -908,7 +892,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void updateCorrelationType(EamArtifact.Type aType) throws EamDbException {
|
||||
public void updateCorrelationType(CorrelationAttribute.Type aType) throws EamDbException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.updateCorrelationType(aType);
|
||||
@ -927,7 +911,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public EamArtifact.Type getCorrelationTypeById(int typeId) throws EamDbException {
|
||||
public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getCorrelationTypeById(typeId);
|
||||
|
@ -403,11 +403,11 @@ public final class SqliteEamDbSettings {
|
||||
stmt.execute(createDbInfoTable.toString());
|
||||
|
||||
// Create a separate instance and reference table for each artifact type
|
||||
List<EamArtifact.Type> DEFAULT_CORRELATION_TYPES = EamArtifact.getDefaultCorrelationTypes();
|
||||
List<CorrelationAttribute.Type> DEFAULT_CORRELATION_TYPES = CorrelationAttribute.getDefaultCorrelationTypes();
|
||||
|
||||
String reference_type_dbname;
|
||||
String instance_type_dbname;
|
||||
for (EamArtifact.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
for (CorrelationAttribute.Type type : DEFAULT_CORRELATION_TYPES) {
|
||||
reference_type_dbname = EamDbUtil.correlationTypeToReferenceTableName(type);
|
||||
instance_type_dbname = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
|
||||
@ -418,7 +418,7 @@ public final class SqliteEamDbSettings {
|
||||
stmt.execute(String.format(instancesIdx4, instance_type_dbname, instance_type_dbname));
|
||||
|
||||
// FUTURE: allow more than the FILES type
|
||||
if (type.getId() == EamArtifact.FILES_TYPE_ID) {
|
||||
if (type.getId() == CorrelationAttribute.FILES_TYPE_ID) {
|
||||
stmt.execute(String.format(createReferenceTypesTableTemplate.toString(), reference_type_dbname, reference_type_dbname));
|
||||
stmt.execute(String.format(referenceTypesIdx1, reference_type_dbname, reference_type_dbname));
|
||||
stmt.execute(String.format(referenceTypesIdx2, reference_type_dbname, reference_type_dbname));
|
||||
|
@ -32,10 +32,10 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDataSource;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
|
||||
@ -139,14 +139,16 @@ public class CaseEventListener implements PropertyChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
final EamArtifact eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af,
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af,
|
||||
knownStatus, comment);
|
||||
|
||||
// send update to Central Repository db
|
||||
Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
|
||||
// TODO: send r into a thread pool instead
|
||||
Thread t = new Thread(r);
|
||||
t.start();
|
||||
if(eamArtifact != null){
|
||||
// send update to Central Repository db
|
||||
Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
|
||||
// TODO: send r into a thread pool instead
|
||||
Thread t = new Thread(r);
|
||||
t.start();
|
||||
}
|
||||
} // CONTENT_TAG_ADDED, CONTENT_TAG_DELETED
|
||||
break;
|
||||
|
||||
@ -220,18 +222,15 @@ public class CaseEventListener implements PropertyChangeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
List<EamArtifact> convertedArtifacts = EamArtifactUtil.fromBlackboardArtifact(bbArtifact, true, dbManager.getCorrelationTypes(), true);
|
||||
for (EamArtifact eamArtifact : convertedArtifacts) {
|
||||
eamArtifact.getInstances().get(0).setComment(comment);
|
||||
Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
|
||||
// TODO: send r into a thread pool instead
|
||||
Thread t = new Thread(r);
|
||||
t.start();
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error, unable to get artifact types during BLACKBOARD_ARTIFACT_TAG_ADDED/BLACKBOARD_ARTIFACT_TAG_DELETED event.", ex);
|
||||
List<CorrelationAttribute> convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
|
||||
for (CorrelationAttribute eamArtifact : convertedArtifacts) {
|
||||
eamArtifact.getInstances().get(0).setComment(comment);
|
||||
Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
|
||||
// TODO: send r into a thread pool instead
|
||||
Thread t = new Thread(r);
|
||||
t.start();
|
||||
}
|
||||
|
||||
} // BLACKBOARD_ARTIFACT_TAG_ADDED, BLACKBOARD_ARTIFACT_TAG_DELETED
|
||||
break;
|
||||
|
||||
@ -245,9 +244,8 @@ public class CaseEventListener implements PropertyChangeListener {
|
||||
|
||||
try {
|
||||
String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId();
|
||||
|
||||
if (null == dbManager.getDataSourceDetails(deviceId)) {
|
||||
dbManager.newDataSource(new EamDataSource(deviceId, newDataSource.getName()));
|
||||
dbManager.newDataSource(CorrelationDataSource.fromTSKDataSource(newDataSource));
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
|
||||
|
@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -49,7 +49,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
*/
|
||||
public class IngestEventsListener {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(EamArtifact.class.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(CorrelationAttribute.class.getName());
|
||||
|
||||
final Collection<String> addedCeArtifactTrackerSet = new LinkedHashSet<>();
|
||||
private static int ceModuleInstanceCount = 0;
|
||||
@ -131,34 +131,32 @@ public class IngestEventsListener {
|
||||
if (null == bbArtifacts) { //the ModuleDataEvents don't always have a collection of artifacts set
|
||||
return;
|
||||
}
|
||||
List<EamArtifact> eamArtifacts = new ArrayList<>();
|
||||
try {
|
||||
for (BlackboardArtifact bbArtifact : bbArtifacts) {
|
||||
// eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
|
||||
List<EamArtifact> convertedArtifacts = EamArtifactUtil.fromBlackboardArtifact(bbArtifact, true, dbManager.getCorrelationTypes(), true);
|
||||
for (EamArtifact eamArtifact : convertedArtifacts) {
|
||||
try {
|
||||
// Only do something with this artifact if it's unique within the job
|
||||
if (addedCeArtifactTrackerSet.add(eamArtifact.toString())) {
|
||||
// Was it previously marked as 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,
|
||||
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
|
||||
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||
if (!caseDisplayNames.isEmpty()) {
|
||||
postCorrelatedBadArtifactToBlackboard(bbArtifact,
|
||||
caseDisplayNames);
|
||||
}
|
||||
eamArtifacts.add(eamArtifact);
|
||||
List<CorrelationAttribute> eamArtifacts = new ArrayList<>();
|
||||
|
||||
for (BlackboardArtifact bbArtifact : bbArtifacts) {
|
||||
// eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
|
||||
List<CorrelationAttribute> convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
|
||||
for (CorrelationAttribute eamArtifact : convertedArtifacts) {
|
||||
try {
|
||||
// Only do something with this artifact if it's unique within the job
|
||||
if (addedCeArtifactTrackerSet.add(eamArtifact.toString())) {
|
||||
// Was it previously marked as 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,
|
||||
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
|
||||
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||
if (!caseDisplayNames.isEmpty()) {
|
||||
postCorrelatedBadArtifactToBlackboard(bbArtifact,
|
||||
caseDisplayNames);
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
|
||||
eamArtifacts.add(eamArtifact);
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
|
||||
}
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting correlation types.", ex);
|
||||
}
|
||||
|
||||
if (FALSE == eamArtifacts.isEmpty()) {
|
||||
// send update to entperirse artifact manager db
|
||||
Runnable r = new NewArtifactsRunner(eamArtifacts);
|
||||
|
@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
@ -33,10 +33,10 @@ public class KnownStatusChangeRunner implements Runnable {
|
||||
private static final Logger LOGGER = Logger.getLogger(KnownStatusChangeRunner.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final EamArtifact artifact;
|
||||
private final CorrelationAttribute artifact;
|
||||
private final FileKnown knownStatus;
|
||||
|
||||
public KnownStatusChangeRunner(EamArtifact artifact, FileKnown knownStatus) {
|
||||
public KnownStatusChangeRunner(CorrelationAttribute artifact, FileKnown knownStatus) {
|
||||
this.artifact = artifact;
|
||||
this.knownStatus = knownStatus;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
|
||||
@ -34,10 +34,10 @@ public class NewArtifactsRunner implements Runnable {
|
||||
private static final Logger LOGGER = Logger.getLogger(NewArtifactsRunner.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Collection<EamArtifact> eamArtifacts;
|
||||
private final Collection<CorrelationAttribute> eamArtifacts;
|
||||
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
public NewArtifactsRunner(Collection<EamArtifact> eamArtifacts) {
|
||||
public NewArtifactsRunner(Collection<CorrelationAttribute> eamArtifacts) {
|
||||
this.eamArtifacts = new ArrayList(eamArtifacts);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class NewArtifactsRunner implements Runnable {
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
|
||||
for (EamArtifact eamArtifact : eamArtifacts) {
|
||||
for (CorrelationAttribute eamArtifact : eamArtifacts) {
|
||||
dbManager.addArtifact(eamArtifact);
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
|
@ -23,6 +23,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -35,9 +36,9 @@ import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDataSource;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -64,9 +65,9 @@ class IngestModule implements FileIngestModule {
|
||||
private static final IngestModuleReferenceCounter warningMsgRefCounter = new IngestModuleReferenceCounter();
|
||||
private long jobId;
|
||||
private EamCase eamCase;
|
||||
private EamDataSource eamDataSource;
|
||||
private CorrelationDataSource eamDataSource;
|
||||
private Blackboard blackboard;
|
||||
private EamArtifact.Type filesType;
|
||||
private CorrelationAttribute.Type filesType;
|
||||
|
||||
@Override
|
||||
public ProcessResult process(AbstractFile af) {
|
||||
@ -137,14 +138,14 @@ class IngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
try {
|
||||
EamArtifact eamArtifact = new EamArtifact(filesType, md5);
|
||||
EamArtifactInstance cefi = new EamArtifactInstance(
|
||||
CorrelationAttribute eamArtifact = new CorrelationAttribute(filesType, md5);
|
||||
CorrelationAttributeInstance cefi = new CorrelationAttributeInstance(
|
||||
eamCase,
|
||||
eamDataSource,
|
||||
af.getParentPath() + af.getName(),
|
||||
null,
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
EamArtifactInstance.GlobalStatus.LOCAL
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
);
|
||||
eamArtifact.addInstance(cefi);
|
||||
dbManager.prepareBulkArtifact(eamArtifact);
|
||||
@ -217,16 +218,13 @@ class IngestModule implements FileIngestModule {
|
||||
jobId = context.getJobId();
|
||||
eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName());
|
||||
|
||||
String deviceId;
|
||||
try {
|
||||
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(context.getDataSource().getId()).getDeviceId();
|
||||
} catch (TskCoreException | TskDataException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting data source device id in ingest module start up.", ex); // NON-NLS
|
||||
throw new IngestModuleException("Error getting data source device id in ingest module start up.", ex); // NON-NLS
|
||||
eamDataSource = CorrelationDataSource.fromTSKDataSource(context.getDataSource());
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting data source info.", ex); // NON-NLS
|
||||
throw new IngestModuleException("Error getting data source info.", ex); // NON-NLS
|
||||
}
|
||||
|
||||
eamDataSource = new EamDataSource(deviceId, context.getDataSource().getName());
|
||||
|
||||
EamDb dbManager;
|
||||
try {
|
||||
dbManager = EamDb.getInstance();
|
||||
@ -236,7 +234,7 @@ class IngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
try {
|
||||
filesType = dbManager.getCorrelationTypeById(EamArtifact.FILES_TYPE_ID);
|
||||
filesType = dbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID);
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS
|
||||
throw new IngestModuleException("Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-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.
|
||||
*/
|
||||
|
@ -50,10 +50,10 @@ import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamGlobalFileInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamGlobalSet;
|
||||
@ -535,7 +535,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
|
||||
// Future, make UI handle more than the "FILES" type.
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
EamArtifact.Type contentType = dbManager.getCorrelationTypeById(EamArtifact.FILES_TYPE_ID); // get "FILES" type
|
||||
CorrelationAttribute.Type contentType = dbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); // get "FILES" type
|
||||
// run in the background and close dialog
|
||||
SwingUtilities.invokeLater(new ImportHashDatabaseWorker(selectedFilePath, knownStatus, globalSetID, contentType)::execute);
|
||||
dispose();
|
||||
@ -577,9 +577,9 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
|
||||
private final TskData.FileKnown knownStatus;
|
||||
private final int globalSetID;
|
||||
private final ProgressHandle progress;
|
||||
private final EamArtifact.Type contentType;
|
||||
private final CorrelationAttribute.Type contentType;
|
||||
|
||||
public ImportHashDatabaseWorker(String filename, TskData.FileKnown knownStatus, int globalSetID, EamArtifact.Type contentType) throws EamDbException, UnknownHostException {
|
||||
public ImportHashDatabaseWorker(String filename, TskData.FileKnown knownStatus, int globalSetID, CorrelationAttribute.Type contentType) throws EamDbException, UnknownHostException {
|
||||
this.file = new File(filename);
|
||||
this.knownStatus = knownStatus;
|
||||
this.globalSetID = globalSetID;
|
||||
|
@ -32,7 +32,7 @@ import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
|
||||
@ -44,7 +44,7 @@ final class ManageCorrelationPropertiesDialog extends javax.swing.JDialog {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ManageCorrelationPropertiesDialog.class.getName());
|
||||
|
||||
private final List<EamArtifact.Type> correlationTypes;
|
||||
private final List<CorrelationAttribute.Type> correlationTypes;
|
||||
|
||||
/**
|
||||
* Displays a dialog that allows a user to select which Type(s) should be
|
||||
@ -73,7 +73,7 @@ final class ManageCorrelationPropertiesDialog extends javax.swing.JDialog {
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
correlationTypes.clear();
|
||||
correlationTypes.addAll(dbManager.getCorrelationTypes());
|
||||
correlationTypes.addAll(dbManager.getDefinedCorrelationTypes());
|
||||
} catch (EamDbException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifact;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
@ -336,9 +336,8 @@ final class ManageTagsDialog extends javax.swing.JDialog {
|
||||
List<BlackboardArtifactTag> artifactTags = curCase.getSleuthkitCase().getBlackboardArtifactTagsByTagName(tagName);
|
||||
|
||||
for(BlackboardArtifactTag bbTag:artifactTags){
|
||||
List<EamArtifact> convertedArtifacts = EamArtifactUtil.fromBlackboardArtifact(bbTag.getArtifact(), true,
|
||||
EamDb.getInstance().getCorrelationTypes(), true);
|
||||
for (EamArtifact eamArtifact : convertedArtifacts) {
|
||||
List<CorrelationAttribute> convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbTag.getArtifact(), true, true);
|
||||
for (CorrelationAttribute eamArtifact : convertedArtifacts) {
|
||||
EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact,TskData.FileKnown.BAD);
|
||||
}
|
||||
}
|
||||
@ -346,9 +345,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
|
||||
// Now search for files
|
||||
List<ContentTag> fileTags = curCase.getSleuthkitCase().getContentTagsByTagName(tagName);
|
||||
for(ContentTag contentTag:fileTags){
|
||||
final EamArtifact eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(),
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(),
|
||||
TskData.FileKnown.BAD, "");
|
||||
EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, TskData.FileKnown.BAD);
|
||||
if(eamArtifact != null){
|
||||
EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, TskData.FileKnown.BAD);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex){
|
||||
throw new EamDbException("Error updating artifacts", ex);
|
||||
|
@ -55,6 +55,7 @@ import org.sleuthkit.autopsy.corecomponents.ResultViewerPersistence.SortCriterio
|
||||
import static org.sleuthkit.autopsy.corecomponents.ResultViewerPersistence.loadSortCriteria;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
@ -204,7 +205,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
||||
|
||||
private static boolean isSupported(Node node) {
|
||||
if (node != null) {
|
||||
Content content = node.getLookup().lookup(Content.class);
|
||||
Content content = node.getLookup().lookup(AbstractFile.class);
|
||||
if (content != null) {
|
||||
return ImageUtils.thumbnailSupported(content);
|
||||
}
|
||||
@ -264,7 +265,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
||||
private ThumbnailViewNode(Node wrappedNode, int thumbSize) {
|
||||
super(wrappedNode, FilterNode.Children.LEAF);
|
||||
this.thumbSize = thumbSize;
|
||||
this.content = this.getLookup().lookup(Content.class);
|
||||
this.content = this.getLookup().lookup(AbstractFile.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-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.datamodel;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
@ -91,6 +109,8 @@ public class CreditCards {
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CreditCards.class.getName());
|
||||
|
||||
|
||||
/**
|
||||
* Range Map from a (ranges of) BINs to data model object with details of
|
||||
* the BIN, ie, bank name, phone, url, visa/amex/mastercard/...,
|
||||
|
@ -286,17 +286,17 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
|
||||
@Override
|
||||
public Boolean visit(LocalFileNode lfn) {
|
||||
return lfn.hasContentChildren();
|
||||
return lfn.hasVisibleContentChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(LayoutFileNode ln) {
|
||||
return ln.hasContentChildren();
|
||||
return ln.hasVisibleContentChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(SlackFileNode sfn) {
|
||||
return sfn.hasContentChildren();
|
||||
return sfn.hasVisibleContentChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -349,19 +349,6 @@ final class AutoIngestJobLogger {
|
||||
log(MessageCategory.WARNING, "Analysis of data source cancelled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs that automated file export is not enabled.
|
||||
*
|
||||
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||
* message.
|
||||
* @throws InterruptedException if interrupted while blocked waiting
|
||||
* to acquire an exclusive lock on the
|
||||
* log file.
|
||||
*/
|
||||
void logFileExportDisabled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||
log(MessageCategory.WARNING, "Automated file export is not enabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs completion of file export.
|
||||
*
|
||||
|
@ -2533,10 +2533,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
||||
if (fileExporter.isEnabled()) {
|
||||
fileExporter.process(manifest.getDeviceId(), dataSource.getContent(), currentJob::isCanceled);
|
||||
jobLogger.logFileExportCompleted();
|
||||
} else {
|
||||
SYS_LOGGER.log(Level.WARNING, "Exporting files not enabled for {0}", manifestPath);
|
||||
jobLogger.logFileExportDisabled();
|
||||
}
|
||||
}
|
||||
} catch (FileExportException ex) {
|
||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex);
|
||||
currentJob.setErrorsOccurred(true);
|
||||
|
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-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.keywordsearch;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
|
||||
|
||||
/**
|
||||
* Utility class to validate Credit Card Numbers. Validation entails checking
|
||||
* that numbers are compatible but not necessarily 'real'. Validation checks the
|
||||
* following properties:
|
||||
* <ul>
|
||||
* <li> A number can have obly one of dashes, spaces, or none as a seperator
|
||||
* character. </li>
|
||||
* <li> If a number has seperator character, the digits must be grouped into a
|
||||
* valid pattern for the number length</li>
|
||||
* <li> A number must pass the luhn check.</li>
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
final class CreditCardValidator {
|
||||
|
||||
private CreditCardValidator() {
|
||||
}
|
||||
|
||||
private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit();
|
||||
|
||||
/**
|
||||
* Does the given string represent a valid credit card number? It must have
|
||||
* no separators, or only '-', or only ' '. Checks digit grouping for
|
||||
* 15,16,and 19 digit numbers. All other length numbers must be contiguous
|
||||
* or begin with a group of 4 digits.
|
||||
*
|
||||
* @param rawCCN
|
||||
*
|
||||
* @return True if rawCCN represents a valid credit card number.
|
||||
*/
|
||||
static public boolean isValidCCN(String rawCCN) {
|
||||
//check for a valid separator
|
||||
boolean hasSpace = StringUtils.contains(rawCCN, ' ');
|
||||
boolean hasDash = StringUtils.contains(rawCCN, '-');
|
||||
if (hasSpace && hasDash) {
|
||||
return false; //can only have dashes or spaces, not both.
|
||||
}
|
||||
|
||||
Character separator = null;
|
||||
if (hasSpace) {
|
||||
separator = ' ';
|
||||
} else if (hasDash) {
|
||||
separator = '-';
|
||||
}
|
||||
|
||||
final String cannonicalCCN;
|
||||
String[] splitCCN;
|
||||
if (separator != null) {
|
||||
//there is a seperator, strip if for canoncial form of CCN
|
||||
cannonicalCCN = CharMatcher.anyOf(separator.toString()).removeFrom(rawCCN);
|
||||
splitCCN = rawCCN.split(separator.toString());
|
||||
} else {
|
||||
//else use 'defualt'values
|
||||
cannonicalCCN = rawCCN;
|
||||
splitCCN = new String[]{cannonicalCCN};
|
||||
}
|
||||
|
||||
// validate digit grouping for 15, 16, and 19 digit cards
|
||||
switch (cannonicalCCN.length()) {
|
||||
case 15:
|
||||
if (false == isValid15DigitGrouping(splitCCN)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (false == isValid16DigitGrouping(splitCCN)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 19:
|
||||
if (false == isValid19DigitGrouping(splitCCN)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (false == isValidOtherDigitGrouping(splitCCN)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN);
|
||||
}
|
||||
|
||||
static private boolean isValidOtherDigitGrouping(String[] splitCCN) {
|
||||
if (splitCCN.length == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return splitCCN[0].length() == 4;
|
||||
}
|
||||
}
|
||||
|
||||
static private boolean isValid19DigitGrouping(String[] splitCCN) {
|
||||
switch (splitCCN.length) {
|
||||
case 1:
|
||||
return true;
|
||||
case 2:
|
||||
return splitCCN[0].length() == 6
|
||||
&& splitCCN[1].length() == 13;
|
||||
case 5:
|
||||
return splitCCN[0].length() == 4
|
||||
&& splitCCN[1].length() == 4
|
||||
&& splitCCN[2].length() == 4
|
||||
&& splitCCN[3].length() == 4
|
||||
&& splitCCN[4].length() == 3;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static private boolean isValid16DigitGrouping(String[] splitCCN) {
|
||||
switch (splitCCN.length) {
|
||||
case 1:
|
||||
return true;
|
||||
case 4:
|
||||
return splitCCN[0].length() == 4
|
||||
&& splitCCN[1].length() == 4
|
||||
&& splitCCN[2].length() == 4
|
||||
&& splitCCN[3].length() == 4;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static private boolean isValid15DigitGrouping(String[] splitCCN) {
|
||||
switch (splitCCN.length) {
|
||||
case 1:
|
||||
return true;
|
||||
case 3:
|
||||
return (splitCCN[0].length() == 4 && splitCCN[1].length() == 6 && splitCCN[2].length() == 5);
|
||||
// UATP || ((splitCCN[0].length() == 4 && splitCCN[1].length() == 5 && splitCCN[2].length() == 6));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -51,13 +51,12 @@ abstract class KeywordSearchList {
|
||||
private static final String URL_REGEX = "(((((h|H)(t|T))|(f|F))(t|T)(p|P)(s|S?)\\:\\/\\/)|(w|W){3,3}\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(\\/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&%\\$#\\=~_\\-]+))*"; //NON-NLS
|
||||
|
||||
/**
|
||||
* 12-19 digits, with possible single spaces or dashes in between, optionally
|
||||
* preceded by % (start sentinel) and a B (format code).
|
||||
* Note that this regular expression is intentionally more broad than the
|
||||
* regular expression used by the code that validates credit card account
|
||||
* numbers. This regex used to attempt to limit hits to numbers starting
|
||||
* with the digits 3 through 6 but this resulted in an error when we
|
||||
* moved to Solr 6.
|
||||
* 12-19 digits, with possible single spaces or dashes in between,
|
||||
* optionally preceded by % (start sentinel) and a B (format code). Note
|
||||
* that this regular expression is intentionally more broad than the regular
|
||||
* expression used by the code that validates credit card account numbers.
|
||||
* This regex used to attempt to limit hits to numbers starting with the
|
||||
* digits 3 through 6 but this resulted in an error when we moved to Solr 6.
|
||||
*/
|
||||
private static final String CCN_REGEX = "(%?)(B?)([0-9][ \\-]*?){12,19}(\\^?)"; //NON-NLS
|
||||
|
||||
|
@ -27,7 +27,7 @@ import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.validator.routines.DomainValidator;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrQuery.SortClause;
|
||||
@ -47,7 +47,9 @@ import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.KEYWORD_SE
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -69,31 +71,33 @@ import org.sleuthkit.datamodel.TskData;
|
||||
final class RegexQuery implements KeywordSearchQuery {
|
||||
|
||||
public static final Logger LOGGER = Logger.getLogger(RegexQuery.class.getName());
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
||||
|
||||
private final KeywordList keywordList;
|
||||
private final Keyword originalKeyword; // The regular expression originalKeyword used to perform the search.
|
||||
private String field = Server.Schema.CONTENT_STR.toString();
|
||||
private final String keywordString;
|
||||
static final private int MAX_RESULTS_PER_CURSOR_MARK = 512;
|
||||
private boolean escaped;
|
||||
private String escapedQuery;
|
||||
|
||||
private final int MIN_EMAIL_ADDR_LENGTH = 8;
|
||||
|
||||
// Lucene regular expressions do not support the following Java predefined
|
||||
// and POSIX character classes. There are other valid Java character classes
|
||||
// that are not supported by Lucene but we do not check for all of them.
|
||||
// See https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
|
||||
// for Java regex syntax.
|
||||
// See https://lucene.apache.org/core/6_4_0/core/org/apache/lucene/util/automaton/RegExp.html
|
||||
// for Lucene syntax.
|
||||
// We use \p as a shortcut for all of the character classes of the form \p{XXX}.
|
||||
/**
|
||||
* Lucene regular expressions do not support the following Java predefined
|
||||
* and POSIX character classes. There are other valid Java character classes
|
||||
* that are not supported by Lucene but we do not check for all of them. See
|
||||
* https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
|
||||
* for Java regex syntax. See
|
||||
* https://lucene.apache.org/core/6_4_0/core/org/apache/lucene/util/automaton/RegExp.html
|
||||
* for Lucene syntax. We use \p as a shortcut for all of the character
|
||||
* classes of the form \p{XXX}.
|
||||
*/
|
||||
private static final CharSequence[] UNSUPPORTED_CHARS = {"\\d", "\\D", "\\w", "\\W", "\\s", "\\S", "\\n",
|
||||
"\\t", "\\r", "\\f", "\\a", "\\e", "\\v", "\\V", "\\h", "\\H", "\\p"}; //NON-NLS
|
||||
|
||||
private boolean queryStringContainsWildcardPrefix = false;
|
||||
private boolean queryStringContainsWildcardSuffix = false;
|
||||
private static final int MAX_RESULTS_PER_CURSOR_MARK = 512;
|
||||
private static final int MIN_EMAIL_ADDR_LENGTH = 8;
|
||||
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
||||
private final KeywordList keywordList;
|
||||
private final Keyword originalKeyword; // The regular expression originalKeyword used to perform the search.
|
||||
private final String keywordString;
|
||||
private final boolean queryStringContainsWildcardPrefix;
|
||||
private final boolean queryStringContainsWildcardSuffix;
|
||||
|
||||
private boolean escaped;
|
||||
private String escapedQuery;
|
||||
private String field = Server.Schema.CONTENT_STR.toString();
|
||||
|
||||
/**
|
||||
* Constructor with query to process.
|
||||
@ -106,13 +110,8 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
this.originalKeyword = keyword;
|
||||
this.keywordString = keyword.getSearchTerm();
|
||||
|
||||
if (this.keywordString.startsWith(".*")) {
|
||||
this.queryStringContainsWildcardPrefix = true;
|
||||
}
|
||||
|
||||
if (this.keywordString.endsWith(".*")) {
|
||||
this.queryStringContainsWildcardSuffix = true;
|
||||
}
|
||||
this.queryStringContainsWildcardPrefix = this.keywordString.startsWith(".*");
|
||||
this.queryStringContainsWildcardSuffix = this.keywordString.endsWith(".*");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -252,6 +251,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
String hit = hitMatcher.group();
|
||||
|
||||
offset = hitMatcher.end();
|
||||
final ATTRIBUTE_TYPE artifactAttributeType = originalKeyword.getArtifactAttributeType();
|
||||
|
||||
// We attempt to reduce false positives for phone numbers and IP address hits
|
||||
// by querying Solr for hits delimited by a set of known boundary characters.
|
||||
@ -260,9 +260,9 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
// needs to be chopped off, unless the user has supplied their own wildcard suffix
|
||||
// as part of the regex.
|
||||
if (!queryStringContainsWildcardSuffix
|
||||
&& (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER
|
||||
|| originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS)) {
|
||||
if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER) {
|
||||
&& (artifactAttributeType == ATTRIBUTE_TYPE.TSK_PHONE_NUMBER
|
||||
|| artifactAttributeType == ATTRIBUTE_TYPE.TSK_IP_ADDRESS)) {
|
||||
if (artifactAttributeType == ATTRIBUTE_TYPE.TSK_PHONE_NUMBER) {
|
||||
// For phone numbers replace all non numeric characters (except "(") at the start of the hit.
|
||||
hit = hit.replaceAll("^[^0-9\\(]", "");
|
||||
} else {
|
||||
@ -273,44 +273,48 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
hit = hit.replaceAll("[^0-9]$", "");
|
||||
}
|
||||
|
||||
if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL) {
|
||||
// Reduce false positives by eliminating email address hits that are either
|
||||
// too short or are not for valid top level domains.
|
||||
if (hit.length() < MIN_EMAIL_ADDR_LENGTH
|
||||
|| !DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
|
||||
continue;
|
||||
if (artifactAttributeType == null) {
|
||||
addHit(content, snippet, hitMatcher, hit, hits, docId);
|
||||
} else {
|
||||
switch (artifactAttributeType) {
|
||||
case TSK_EMAIL:
|
||||
/*
|
||||
* Reduce false positives by eliminating email
|
||||
* address hits that are either too short or are
|
||||
* not for valid top level domains.
|
||||
*/
|
||||
if (hit.length() >= MIN_EMAIL_ADDR_LENGTH
|
||||
&& DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
|
||||
addHit(content, snippet, hitMatcher, hit, hits, docId);
|
||||
}
|
||||
|
||||
break;
|
||||
case TSK_CARD_NUMBER:
|
||||
/*
|
||||
* If searching for credit card account numbers,
|
||||
* do extra validation on the term and discard
|
||||
* it if it does not pass.
|
||||
*/
|
||||
Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
|
||||
|
||||
for (int rLength = hit.length(); rLength >= 12; rLength--) {
|
||||
ccnMatcher.region(0, rLength);
|
||||
if (ccnMatcher.find()) {
|
||||
final String group = ccnMatcher.group("ccn");
|
||||
if (CreditCardValidator.isValidCCN(group)) {
|
||||
addHit(content, snippet, hitMatcher, hit, hits, docId);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
addHit(content, snippet, hitMatcher, hit, hits, docId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If searching for credit card account numbers, do a Luhn
|
||||
* check on the term and discard it if it does not pass.
|
||||
*/
|
||||
if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
|
||||
Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
|
||||
if (ccnMatcher.find()) {
|
||||
final String ccn = CharMatcher.anyOf(" -").removeFrom(ccnMatcher.group("ccn"));
|
||||
if (false == TermsComponentQuery.CREDIT_CARD_NUM_LUHN_CHECK.isValid(ccn)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the snippet from the document if keyword search is
|
||||
* configured to use snippets.
|
||||
*/
|
||||
int maxIndex = content.length() - 1;
|
||||
snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start())));
|
||||
snippet.appendCodePoint(171);
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
throw ex;
|
||||
@ -328,6 +332,21 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
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
|
||||
* use snippets.
|
||||
*/
|
||||
int maxIndex = content.length() - 1;
|
||||
snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start())));
|
||||
snippet.appendCodePoint(171);
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFilter(KeywordQueryFilter filter) {
|
||||
this.filters.add(filter);
|
||||
@ -390,11 +409,11 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
*/
|
||||
BlackboardArtifact newArtifact;
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
if (originalKeyword.getArtifactAttributeType() != BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm()));
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString()));
|
||||
if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm()));
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString()));
|
||||
try {
|
||||
newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS
|
||||
return null;
|
||||
@ -404,7 +423,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* Parse the credit card account attributes from the snippet for the
|
||||
* hit.
|
||||
*/
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.name()));
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.name()));
|
||||
Map<BlackboardAttribute.Type, BlackboardAttribute> parsedTrackAttributeMap = new HashMap<>();
|
||||
Matcher matcher = TermsComponentQuery.CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet());
|
||||
if (matcher.find()) {
|
||||
@ -414,7 +433,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
if (matcher.find()) {
|
||||
parseTrack2Data(parsedTrackAttributeMap, matcher);
|
||||
}
|
||||
final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER));
|
||||
final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER));
|
||||
if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) {
|
||||
if (hit.isArtifactHit()) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS
|
||||
@ -433,21 +452,21 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin);
|
||||
if (binInfo != null) {
|
||||
binInfo.getScheme().ifPresent(scheme
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme)));
|
||||
binInfo.getCardType().ifPresent(cardType
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType)));
|
||||
binInfo.getBrand().ifPresent(brand
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand)));
|
||||
binInfo.getBankName().ifPresent(bankName
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName)));
|
||||
binInfo.getBankPhoneNumber().ifPresent(phoneNumber
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber)));
|
||||
binInfo.getBankURL().ifPresent(url
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url)));
|
||||
binInfo.getCountry().ifPresent(country
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country)));
|
||||
binInfo.getBankCity().ifPresent(city
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city)));
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city)));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -467,7 +486,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* Create an account artifact.
|
||||
*/
|
||||
try {
|
||||
newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS
|
||||
return null;
|
||||
@ -475,17 +494,17 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(listName)) {
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName));
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName));
|
||||
}
|
||||
if (snippet != null) {
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet));
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet));
|
||||
}
|
||||
|
||||
|
||||
hit.getArtifactID().ifPresent(artifactID
|
||||
-> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID))
|
||||
-> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID))
|
||||
);
|
||||
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal()));
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal()));
|
||||
|
||||
try {
|
||||
newArtifact.addAttributes(attributes);
|
||||
@ -505,11 +524,11 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* @param matcher A matcher for the snippet.
|
||||
*/
|
||||
static private void parseTrack2Data(Map<BlackboardAttribute.Type, BlackboardAttribute> attributesMap, Matcher matcher) {
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER, "accountNumber", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_EXPIRATION, "expiration", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_SERVICE_CODE, "serviceCode", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_DISCRETIONARY, "discretionary", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_LRC, "LRC", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, ATTRIBUTE_TYPE.TSK_CARD_NUMBER, "accountNumber", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, ATTRIBUTE_TYPE.TSK_CARD_EXPIRATION, "expiration", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, ATTRIBUTE_TYPE.TSK_CARD_SERVICE_CODE, "serviceCode", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, ATTRIBUTE_TYPE.TSK_CARD_DISCRETIONARY, "discretionary", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributesMap, ATTRIBUTE_TYPE.TSK_CARD_LRC, "LRC", matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -518,12 +537,12 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* same fields as the track two data, plus the account holder's name.
|
||||
*
|
||||
* @param attributeMap A map of artifact attribute objects, used to avoid
|
||||
* creating duplicate attributes.
|
||||
* @param matcher A matcher for the snippet.
|
||||
* creating duplicate attributes.
|
||||
* @param matcher A matcher for the snippet.
|
||||
*/
|
||||
static private void parseTrack1Data(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, Matcher matcher) {
|
||||
parseTrack2Data(attributeMap, matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributeMap, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME_PERSON, "name", matcher);
|
||||
addAttributeIfNotAlreadyCaptured(attributeMap, ATTRIBUTE_TYPE.TSK_NAME_PERSON, "name", matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -531,20 +550,20 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* value parsed from the snippet for a credit account number hit.
|
||||
*
|
||||
* @param attributeMap A map of artifact attribute objects, used to avoid
|
||||
* creating duplicate attributes.
|
||||
* @param attrType The type of attribute to create.
|
||||
* @param groupName The group name of the regular expression that was
|
||||
* used to parse the attribute data.
|
||||
* @param matcher A matcher for the snippet.
|
||||
|
||||
* creating duplicate attributes.
|
||||
* @param attrType The type of attribute to create.
|
||||
* @param groupName The group name of the regular expression that was
|
||||
* used to parse the attribute data.
|
||||
* @param matcher A matcher for the snippet.
|
||||
*
|
||||
*/
|
||||
static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, BlackboardAttribute.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);
|
||||
attributeMap.computeIfAbsent(type, (BlackboardAttribute.Type t) -> {
|
||||
String value = matcher.group(groupName);
|
||||
if (attrType.equals(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) {
|
||||
attributeMap.put(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD),
|
||||
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, value));
|
||||
if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) {
|
||||
attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD),
|
||||
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, value));
|
||||
value = CharMatcher.anyOf(" -").removeFrom(value);
|
||||
}
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
|
@ -30,7 +30,6 @@ import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -62,19 +61,26 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
private static final String CASE_INSENSITIVE = "case_insensitive"; //NON-NLS
|
||||
private static final boolean DEBUG_FLAG = Version.Type.DEVELOPMENT.equals(Version.getBuildType());
|
||||
private static final int MAX_TERMS_QUERY_RESULTS = 20000;
|
||||
|
||||
private final KeywordList keywordList;
|
||||
private final Keyword originalKeyword;
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<>(); // THIS APPEARS TO BE UNUSED
|
||||
|
||||
private String searchTerm;
|
||||
private boolean searchTermIsEscaped;
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<>(); // THIS APPEARS TO BE UNUSED
|
||||
|
||||
/*
|
||||
* The following fields are part of the initial implementation of credit
|
||||
* card account search and should be factored into another class when time
|
||||
* permits.
|
||||
*/
|
||||
static final Pattern CREDIT_CARD_NUM_PATTERN = Pattern.compile("(?<ccn>[3-6]([ -]?[0-9]){11,18})"); //12-19 digits, with possible single spaces or dashes in between. First digit is 3,4,5, or 6 //NON-NLS
|
||||
static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit();
|
||||
/**
|
||||
* 12-19 digits, with possible single spaces or dashes in between. First
|
||||
* digit is 2 through 6
|
||||
*
|
||||
*/
|
||||
static final Pattern CREDIT_CARD_NUM_PATTERN =
|
||||
Pattern.compile("(?<ccn>[2-6]([ -]?[0-9]){11,18})");
|
||||
static final Pattern CREDIT_CARD_TRACK1_PATTERN = Pattern.compile(
|
||||
/*
|
||||
* Track 1 is alphanumeric.
|
||||
@ -87,7 +93,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
"(?:" //begin nested optinal group //NON-NLS
|
||||
+ "%?" //optional start sentinal: % //NON-NLS
|
||||
+ "B)?" //format code //NON-NLS
|
||||
+ "(?<accountNumber>[3-6]([ -]?[0-9]){11,18})" //12-19 digits, with possible single spaces or dashes in between. first digit is 3,4,5, or 6 //NON-NLS
|
||||
+ "(?<accountNumber>[2-6]([ -]?[0-9]){11,18})" //12-19 digits, with possible single spaces or dashes in between. first digit is 2,3,4,5, or 6 //NON-NLS
|
||||
+ "\\^" //separator //NON-NLS
|
||||
+ "(?<name>[^^]{2,26})" //2-26 charachter name, not containing ^ //NON-NLS
|
||||
+ "(?:\\^" //separator //NON-NLS
|
||||
@ -108,7 +114,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
*
|
||||
*/
|
||||
"[:;<=>?]?" //(optional)start sentinel //NON-NLS
|
||||
+ "(?<accountNumber>[3-6]([ -]?[0-9]){11,18})" //12-19 digits, with possible single spaces or dashes in between. first digit is 3,4,5, or 6 //NON-NLS
|
||||
+ "(?<accountNumber>[2-6]([ -]?[0-9]){11,18})" //12-19 digits, with possible single spaces or dashes in between. first digit is 2,3,4,5, or 6 //NON-NLS
|
||||
+ "(?:[:;<=>?]" //separator //NON-NLS
|
||||
+ "(?:(?<expiration>\\d{4})" //4 digit expiration date YYMM //NON-NLS
|
||||
+ "(?:(?<serviceCode>\\d{3})" //3 digit service code //NON-NLS
|
||||
@ -118,6 +124,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
+ "?)?)?)?)?)?"); //close nested optional groups //NON-NLS
|
||||
static final BlackboardAttribute.Type KEYWORD_SEARCH_DOCUMENT_ID = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID);
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an object that implements a regex query that will be performed
|
||||
* as a two step operation. In the first step, the Solr terms component is
|
||||
@ -289,9 +296,8 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
*/
|
||||
if (originalKeyword.getArtifactAttributeType() == ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
|
||||
Matcher matcher = CREDIT_CARD_NUM_PATTERN.matcher(term.getTerm());
|
||||
matcher.find();
|
||||
final String ccn = CharMatcher.anyOf(" -").removeFrom(matcher.group("ccn"));
|
||||
if (false == CREDIT_CARD_NUM_LUHN_CHECK.isValid(ccn)) {
|
||||
if (false == matcher.find()
|
||||
|| false == CreditCardValidator.isValidCCN(matcher.group("ccn"))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -319,7 +325,6 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
/*
|
||||
@ -460,9 +465,9 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
* hit and turns them into artifact attributes. The track 1 data has the
|
||||
* same fields as the track two data, plus the account holder's name.
|
||||
*
|
||||
* @param attributesMap A map of artifact attribute objects, used to avoid
|
||||
* creating duplicate attributes.
|
||||
* @param matcher A matcher for the snippet.
|
||||
* @param attributeMap A map of artifact attribute objects, used to avoid
|
||||
* creating duplicate attributes.
|
||||
* @param matcher A matcher for the snippet.
|
||||
*/
|
||||
static private void parseTrack1Data(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, Matcher matcher) {
|
||||
parseTrack2Data(attributeMap, matcher);
|
||||
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-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.keywordsearch;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CreditCardValidatorTest {
|
||||
|
||||
public CreditCardValidatorTest() {
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of isValidCCN method, of class CreditCardValidator.
|
||||
*/
|
||||
@Test
|
||||
public void testIsValidCCN16() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
//rules for separators and grouping for 16 digits
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234567890318342"));// dashes
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-5678-9031-8342"));// dashes
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342"));// or spaces
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234567890318341"));// luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-9031 8342")); //only one seperator
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-90-318342")); //only four groups of four
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234 5678 90 318342")); //only four groups of four
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1-2-3-4-5-6-7-8-9-0-3-1-8-3-4-2")); //only four groups of four
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN15() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
//amex are fifteen digits, and grouped 4 6 5
|
||||
//amex cards that strart with 34
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("3431 136294 58529"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("3431-136294-58529"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("343113629458529"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("343113629458528")); //luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("3431 13629458 529")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("3431 136294-58529")); //separators
|
||||
|
||||
//amex cards that start with 37
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("377585291285489"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("3775-852912-85489"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("3775 852912 85489"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("377585291285488")); //luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("3775-852912 85489")); //separator
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("37-7585-29-1285489")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("377585 29128548 9")); //grouping
|
||||
|
||||
//UATP are also 15 digits, start with 1 and are typically 4-5-6
|
||||
// assertEquals(true, CreditCardValidator.isValidCCN("1409 56201 545229"));
|
||||
// assertEquals(true, CreditCardValidator.isValidCCN("1409-56201-545229"));
|
||||
// assertEquals(true, CreditCardValidator.isValidCCN("140956201545229"));
|
||||
// assertEquals(false, CreditCardValidator.isValidCCN("140 9562015 45229"));
|
||||
// assertEquals(false, CreditCardValidator.isValidCCN("1409-56201 545229"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN19() {
|
||||
System.out.println("isValidCCN");
|
||||
//nineteen digit (visa) cards 4-4-4-4-3
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("4539747947839518654"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("4539-7479-4783-9518-654"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("4539 7479 4783 9518 654"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("4539747947839518653")); //luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("4539-7479 4783 9518 654")); //separators
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("45374 79 4783 9518 654")); //grouping
|
||||
|
||||
//nineteen digit China UnionPay is 19 digits 6-13 (or 4-4-4-4) beging 62
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("6239747947839518659"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("623974 7947839518659"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("623974-7947839518659"));
|
||||
/*
|
||||
* China UnionPay may not use luhn ???
|
||||
*
|
||||
* 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("623974-79478395 18659")); //separators
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("62397-47947839518659")); //grouping
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN18() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("123456789031834267"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 67"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-267"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123456789031834266")); //luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123 456789031834267")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031834267")); //separators
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN17() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("12345678903183426"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 6"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-26"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("12345678903183425"));//luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183426")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183426")); //separators
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN14() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("12345678903183"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 83"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-5678903183"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("12345678903182"));//luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183")); //separators
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN13() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234567890318"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-567890318"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234567890317"));//luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123 4567890318")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 0318")); //separators
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidCCN12() {
|
||||
System.out.println("isValidCCN");
|
||||
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("123456789031"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031"));
|
||||
assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031"));
|
||||
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123456789030")); //luhn
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping
|
||||
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators
|
||||
}
|
||||
}
|
@ -263,9 +263,11 @@
|
||||
<target name="build-installer" depends="getProps, doxygen, build-zip" description="Builds Autopsy installer.">
|
||||
<delete dir="${nbdist.dir}/${app.name}-installer" quiet="true"/>
|
||||
<unzip src="${nbdist.dir}/${app.name}-${app.version}.zip" dest="${nbdist.dir}/${app.name}-installer"/>
|
||||
<!-- Disable the Experimental module by default for the installed version -->
|
||||
|
||||
<!-- Disable the Experimental module by default for the installed version. Need to update .lastModified time for change to be seen. -->
|
||||
<replace file="${nbdist.dir}/${app.name}-installer/autopsy/config/modules/org-sleuthkit-autopsy-experimental.xml" token="<param name="enabled">true</param>" value="<param name="enabled">false</param>"/>
|
||||
<echo file="${nbdist.dir}/${app.name}-installer/autopsy/.lastModified" message="" />
|
||||
|
||||
<antcall target="build-installer-${os.family}" />
|
||||
</target>
|
||||
</project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user