Merge pull request #5896 from gdicristofaro/6359-removeCommenting

6359 remove commenting
This commit is contained in:
Richard Cordovano 2020-05-18 09:30:28 -04:00 committed by GitHub
commit 137c3ff74d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 356 additions and 265 deletions

View File

@ -41,6 +41,7 @@ import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -81,7 +82,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
private static final Cache<Pair<CentralRepoAccountType, String>, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder() private static final Cache<Pair<CentralRepoAccountType, String>, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder()
.expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES). .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES).
build(); build();
private boolean isCRTypeCacheInitialized; private boolean isCRTypeCacheInitialized;
private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build(); private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build();
private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder() private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
@ -104,8 +105,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
static final int DEFAULT_BULK_THRESHHOLD = 1000; static final int DEFAULT_BULK_THRESHHOLD = 1000;
private static final int QUERY_STR_MAX_LEN = 1000; private static final int QUERY_STR_MAX_LEN = 1000;
/** /**
* Connect to the DB and initialize it. * Connect to the DB and initialize it.
* *
@ -136,6 +136,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
* Get an ephemeral connection. * Get an ephemeral connection.
*/ */
protected abstract Connection getEphemeralConnection(); protected abstract Connection getEphemeralConnection();
/** /**
* Add a new name/value pair in the db_info table. * Add a new name/value pair in the db_info table.
* *
@ -222,7 +223,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
* Reset the contents of the caches associated with EamDb results. * Reset the contents of the caches associated with EamDb results.
*/ */
public final void clearCaches() { public final void clearCaches() {
synchronized(typeCache) { synchronized (typeCache) {
typeCache.invalidateAll(); typeCache.invalidateAll();
isCRTypeCacheInitialized = false; isCRTypeCacheInitialized = false;
} }
@ -1016,27 +1017,26 @@ abstract class RdbmsCentralRepo implements CentralRepository {
// @@@ We should cache the case and data source IDs in memory // @@@ We should cache the case and data source IDs in memory
String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType()); boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType());
String sql; String sql;
// _instance table for accounts have an additional account_id column // _instance table for accounts have an additional account_id column
if (artifactHasAnAccount) { if (artifactHasAnAccount) {
sql = "INSERT INTO " sql = "INSERT INTO "
+ tableName + tableName
+ "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
+ getConflictClause(); + getConflictClause();
} } else {
else { sql = "INSERT INTO "
sql = "INSERT INTO " + tableName
+ tableName + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
+ "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " + "VALUES (?, ?, ?, ?, ?, ?, ?) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?) " + getConflictClause();
+ getConflictClause();
} }
try (Connection conn = connect(); try (Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);) { PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
if (!eamArtifact.getCorrelationValue().isEmpty()) { if (!eamArtifact.getCorrelationValue().isEmpty()) {
preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID()); preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID());
preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID()); preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID());
@ -1050,7 +1050,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
preparedStatement.setString(6, eamArtifact.getComment()); preparedStatement.setString(6, eamArtifact.getComment());
} }
preparedStatement.setLong(7, eamArtifact.getFileObjectId()); preparedStatement.setLong(7, eamArtifact.getFileObjectId());
// set in the accountId only for artifacts that represent accounts // set in the accountId only for artifacts that represent accounts
if (artifactHasAnAccount) { if (artifactHasAnAccount) {
if (eamArtifact.getAccountId() >= 0) { if (eamArtifact.getAccountId() >= 0) {
@ -1065,21 +1065,21 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new CentralRepoException("Error inserting new artifact into artifacts table.", ex); // NON-NLS throw new CentralRepoException("Error inserting new artifact into artifacts table.", ex); // NON-NLS
} }
} }
/** /**
* Gets the Central Repo account for the given account type and account ID. * Gets the Central Repo account for the given account type and account ID.
* Create a new account first, if one doesn't exist * Create a new account first, if one doesn't exist
* *
* @param accountType account type * @param accountType account type
* @param accountUniqueID unique account identifier * @param accountUniqueID unique account identifier
* *
* @return A matching account, either existing or newly created. * @return A matching account, either existing or newly created.
* *
* @throws TskCoreException exception thrown if a critical error occurs * @throws TskCoreException exception thrown if a critical error occurs
* within TSK core * within TSK core
*/ */
@Override @Override
public CentralRepoAccount getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { public CentralRepoAccount getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException {
// Get the account fom the accounts table // Get the account fom the accounts table
@ -1105,56 +1105,53 @@ abstract class RdbmsCentralRepo implements CentralRepository {
return account; return account;
} }
@Override @Override
public CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException { public CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException {
try { try {
return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName)); return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName));
} catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) { } catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
throw new CentralRepoException("Error looking up CR account type in cache.", ex); throw new CentralRepoException("Error looking up CR account type in cache.", ex);
} }
} }
@Override @Override
public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException { public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException {
Collection<CentralRepoAccountType> accountTypes = new ArrayList<>();
String sql = "SELECT * FROM account_types";
try ( Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
Collection<CentralRepoAccountType> accountTypes = new ArrayList<>();
String sql = "SELECT * FROM account_types";
try (Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
try (ResultSet resultSet = preparedStatement.executeQuery();) { try (ResultSet resultSet = preparedStatement.executeQuery();) {
while (resultSet.next()) { while (resultSet.next()) {
Account.Type acctType = new Account.Type(resultSet.getString("type_name"), resultSet.getString("display_name")); Account.Type acctType = new Account.Type(resultSet.getString("type_name"), resultSet.getString("display_name"));
CentralRepoAccountType crAccountType = new CentralRepoAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id")); CentralRepoAccountType crAccountType = new CentralRepoAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id"));
accountTypes.add(crAccountType); accountTypes.add(crAccountType);
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
throw new CentralRepoException("Error getting account types from central repository.", ex); // NON-NLS throw new CentralRepoException("Error getting account types from central repository.", ex); // NON-NLS
} }
return accountTypes; return accountTypes;
} }
/** /**
* Gets the CR account type for the specified type name. * Gets the CR account type for the specified type name.
* *
* @param accountTypeName account type name to look for * @param accountTypeName account type name to look for
*
* @return CR account type * @return CR account type
* *
* @throws CentralRepoException * @throws CentralRepoException
*/ */
private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException { private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException {
String sql = "SELECT * FROM account_types WHERE type_name = ?"; String sql = "SELECT * FROM account_types WHERE type_name = ?";
try ( Connection conn = connect(); try (Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);) { PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
preparedStatement.setString(1, accountTypeName); preparedStatement.setString(1, accountTypeName);
try (ResultSet resultSet = preparedStatement.executeQuery();) { try (ResultSet resultSet = preparedStatement.executeQuery();) {
@ -1169,24 +1166,27 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} }
} catch (SQLException ex) { } catch (SQLException ex) {
throw new CentralRepoException("Error getting correlation type by id.", ex); // NON-NLS throw new CentralRepoException("Error getting correlation type by id.", ex); // NON-NLS
} }
} }
/** /**
* Get the CR account with the given account type and the unique account identifier. * Get the CR account with the given account type and the unique account
* Looks in the cache first. * identifier. Looks in the cache first. If not found in cache, reads from
* If not found in cache, reads from the database and saves in cache. * the database and saves in cache.
* *
* Returns null if the account is not found in the cache and not in the database. * Returns null if the account is not found in the cache and not in the
* * database.
* @param crAccountType account type to look for *
* @param crAccountType account type to look for
* @param accountUniqueID unique account id * @param accountUniqueID unique account id
* @return CentralRepoAccount for the give type/id. May return null if not found. *
* * @return CentralRepoAccount for the give type/id. May return null if not
* @throws CentralRepoException * found.
*
* @throws CentralRepoException
*/ */
private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException {
CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID)); CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID));
if (crAccount == null) { if (crAccount == null) {
crAccount = getCRAccountFromDb(crAccountType, accountUniqueID); crAccount = getCRAccountFromDb(crAccountType, accountUniqueID);
@ -1194,30 +1194,29 @@ abstract class RdbmsCentralRepo implements CentralRepository {
accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount); accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount);
} }
} }
return crAccount; return crAccount;
} }
/** /**
* Get the Account with the given account type and account identifier, * Get the Account with the given account type and account identifier, from
* from the database. * the database.
* *
* @param accountType account type * @param accountType account type
* @param accountUniqueID unique account identifier * @param accountUniqueID unique account identifier
* *
* @return Account, returns NULL is no matching account found * @return Account, returns NULL is no matching account found
* *
* @throws TskCoreException exception thrown if a critical error occurs * @throws TskCoreException exception thrown if a critical error occurs
* within TSK core * within TSK core
*/ */
private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException {
CentralRepoAccount account = null; CentralRepoAccount account = null;
String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?"; String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
try ( Connection connection = connect(); try (Connection connection = connect();
PreparedStatement preparedStatement = connection.prepareStatement(sql);) { PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
preparedStatement.setInt(1, crAccountType.getAccountTypeId()); preparedStatement.setInt(1, crAccountType.getAccountTypeId());
preparedStatement.setString(2, accountUniqueID); preparedStatement.setString(2, accountUniqueID);
@ -1233,8 +1232,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
return account; return account;
} }
private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact) throws CentralRepoException {
if (eamArtifact == null) { if (eamArtifact == null) {
throw new CentralRepoException("CorrelationAttribute is null"); throw new CentralRepoException("CorrelationAttribute is null");
@ -1575,7 +1573,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
synchronized (bulkArtifacts) { synchronized (bulkArtifacts) {
if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) { if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()), new ArrayList<>()); bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()), new ArrayList<>());
} }
bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact); bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
bulkArtifactsCount++; bulkArtifactsCount++;
@ -2002,8 +2000,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
String sqlUpdate String sqlUpdate
= "UPDATE " = "UPDATE "
+ tableName + tableName
+ " SET known_status=?, comment=? " + " SET known_status=? WHERE id=?";
+ "WHERE id=?";
try { try {
preparedQuery = conn.prepareStatement(sqlQuery); preparedQuery = conn.prepareStatement(sqlQuery);
@ -2017,15 +2014,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
preparedUpdate = conn.prepareStatement(sqlUpdate); preparedUpdate = conn.prepareStatement(sqlUpdate);
preparedUpdate.setByte(1, knownStatus.getFileKnownValue()); preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
// NOTE: if the user tags the same instance as BAD multiple times, preparedUpdate.setInt(2, instance_id);
// the comment from the most recent tagging is the one that will
// prevail in the DB.
if ("".equals(eamArtifact.getComment())) {
preparedUpdate.setNull(2, Types.INTEGER);
} else {
preparedUpdate.setString(2, eamArtifact.getComment());
}
preparedUpdate.setInt(3, instance_id);
preparedUpdate.executeUpdate(); preparedUpdate.executeUpdate();
} else { } else {
@ -2332,8 +2321,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
HashHitInfo found = new HashHitInfo(hashFound, "", ""); HashHitInfo found = new HashHitInfo(hashFound, "", "");
found.addComment(comment); found.addComment(comment);
return found; return found;
} } else {
else {
return null; return null;
} }
} catch (SQLException ex) { } catch (SQLException ex) {
@ -2344,8 +2332,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
CentralRepoDbUtil.closeConnection(conn); CentralRepoDbUtil.closeConnection(conn);
} }
} }
/** /**
* Check if the given value is in a specific reference set * Check if the given value is in a specific reference set
@ -2516,7 +2502,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
CentralRepoDbUtil.closeConnection(conn); CentralRepoDbUtil.closeConnection(conn);
} }
} }
/** /**
* Process a SELECT query * Process a SELECT query
* *
@ -2554,7 +2540,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
CentralRepoDbUtil.closeResultSet(resultSet); CentralRepoDbUtil.closeResultSet(resultSet);
CentralRepoDbUtil.closeConnection(conn); CentralRepoDbUtil.closeConnection(conn);
} }
} }
@Override @Override
public void executeInsertSQL(String insertClause) throws CentralRepoException { public void executeInsertSQL(String insertClause) throws CentralRepoException {
@ -2597,7 +2583,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
throw new CentralRepoException(String.format("Error running SQL %s, exception = %s", selectSQL, ex.getMessage()), ex); throw new CentralRepoException(String.format("Error running SQL %s, exception = %s", selectSQL, ex.getMessage()), ex);
} }
} }
@Override @Override
public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg) throws CentralRepoException { public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg) throws CentralRepoException {
if (eamOrg == null) { if (eamOrg == null) {
@ -2737,15 +2723,16 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} }
/** /**
* Queries the examiner table for the given user name. * Queries the examiner table for the given user name. Adds a row if the
* Adds a row if the user is not found in the examiner table. * user is not found in the examiner table.
* *
* @param examinerLoginName user name to look for. * @param examinerLoginName user name to look for.
*
* @return CentralRepoExaminer for the given user name. * @return CentralRepoExaminer for the given user name.
*
* @throws CentralRepoException If there is an error in looking up or * @throws CentralRepoException If there is an error in looking up or
* inserting the user in the examiners table. * inserting the user in the examiners table.
*/ */
@Override @Override
public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException { public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException {
@ -2770,7 +2757,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
default: default:
throw new CentralRepoException(String.format("Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform())); //NON-NLS throw new CentralRepoException(String.format("Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform())); //NON-NLS
} }
statement.execute(insertSQL); statement.execute(insertSQL);
// Query the table again to get the row for the user // Query the table again to get the row for the user
try (ResultSet resultSet2 = statement.executeQuery(querySQL)) { try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
@ -2790,7 +2777,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
throw new CentralRepoException("Error getting examiner for name = " + examinerLoginName, ex); throw new CentralRepoException("Error getting examiner for name = " + examinerLoginName, ex);
} }
} }
/** /**
* Update an existing organization. * Update an existing organization.
* *
@ -3185,7 +3172,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
typeId = newCorrelationTypeKnownId(newType); typeId = newCorrelationTypeKnownId(newType);
} }
synchronized(typeCache) { synchronized (typeCache) {
typeCache.put(newType.getId(), newType); typeCache.put(newType.getId(), newType);
} }
return typeId; return typeId;
@ -3402,7 +3389,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0); preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
preparedStatement.setInt(5, aType.getId()); preparedStatement.setInt(5, aType.getId());
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();
synchronized(typeCache) { synchronized (typeCache) {
typeCache.put(aType.getId(), aType); typeCache.put(aType.getId(), aType);
} }
} catch (SQLException ex) { } catch (SQLException ex) {
@ -3426,7 +3413,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
@Override @Override
public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws CentralRepoException { public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws CentralRepoException {
try { try {
synchronized(typeCache) { synchronized (typeCache) {
return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId)); return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
} }
} catch (CacheLoader.InvalidCacheLoadException ignored) { } catch (CacheLoader.InvalidCacheLoadException ignored) {
@ -3437,7 +3424,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} }
} }
/** /**
* Get the EamArtifact.Type that has the given Type.Id from the central repo * Get the EamArtifact.Type that has the given Type.Id from the central repo
* *
@ -3476,24 +3462,25 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} }
/** /**
* Reads the correlation types from the database and loads them up in the cache. * Reads the correlation types from the database and loads them up in the
* * cache.
*
* @throws CentralRepoException If there is an error. * @throws CentralRepoException If there is an error.
*/ */
private void getCorrelationTypesFromCr() throws CentralRepoException { private void getCorrelationTypesFromCr() throws CentralRepoException {
// clear out the cache // clear out the cache
synchronized(typeCache) { synchronized (typeCache) {
typeCache.invalidateAll(); typeCache.invalidateAll();
isCRTypeCacheInitialized = false; isCRTypeCacheInitialized = false;
} }
String sql = "SELECT * FROM correlation_types";
try ( Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();) {
synchronized(typeCache) { String sql = "SELECT * FROM correlation_types";
try (Connection conn = connect();
PreparedStatement preparedStatement = conn.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();) {
synchronized (typeCache) {
while (resultSet.next()) { while (resultSet.next()) {
CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet); CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
typeCache.put(aType.getId(), aType); typeCache.put(aType.getId(), aType);
@ -3502,9 +3489,9 @@ abstract class RdbmsCentralRepo implements CentralRepository {
} }
} catch (SQLException ex) { } catch (SQLException ex) {
throw new CentralRepoException("Error getting correlation types.", ex); // NON-NLS throw new CentralRepoException("Error getting correlation types.", ex); // NON-NLS
} }
} }
/** /**
* Convert a ResultSet to a EamCase object * Convert a ResultSet to a EamCase object
* *
@ -3662,13 +3649,13 @@ abstract class RdbmsCentralRepo implements CentralRepository {
case POSTGRESQL: case POSTGRESQL:
return "INSERT " + sql + " ON CONFLICT DO NOTHING"; //NON-NLS return "INSERT " + sql + " ON CONFLICT DO NOTHING"; //NON-NLS
case SQLITE: case SQLITE:
return "INSERT OR IGNORE " + sql; return "INSERT OR IGNORE " + sql;
default: default:
throw new CentralRepoException("Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform()); throw new CentralRepoException("Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform());
} }
} }
/** /**
* Determine if a specific column already exists in a specific table * Determine if a specific column already exists in a specific table
* *
@ -3781,7 +3768,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
*/ */
if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 2)) < 0) { if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 2)) < 0) {
final String addIntegerColumnTemplate = "ALTER TABLE %s ADD COLUMN %s INTEGER;"; //NON-NLS final String addIntegerColumnTemplate = "ALTER TABLE %s ADD COLUMN %s INTEGER;"; //NON-NLS
final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform); final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(); final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(); final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
@ -3801,7 +3788,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
default: default:
throw new CentralRepoException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name())); throw new CentralRepoException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
} }
final String dataSourcesTableName = "data_sources"; final String dataSourcesTableName = "data_sources";
final String dataSourceObjectIdColumnName = "datasource_obj_id"; final String dataSourceObjectIdColumnName = "datasource_obj_id";
if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) { if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
@ -3966,7 +3953,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
// Upgrade to 1.4 // Upgrade to 1.4
(new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn); (new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
// Upgrade to 1.5 // Upgrade to 1.5
(new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn); (new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);

View File

@ -27,7 +27,6 @@ import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -55,6 +54,7 @@ import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
/** /**
@ -67,12 +67,12 @@ final class CaseEventListener implements PropertyChangeListener {
private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName()); private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName());
private final ExecutorService jobProcessingExecutor; private final ExecutorService jobProcessingExecutor;
private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d"; private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d";
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of( private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED,
Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED,
Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED,
Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_ADDED,
Case.Events.TAG_DEFINITION_CHANGED, Case.Events.TAG_DEFINITION_CHANGED,
Case.Events.CURRENT_CASE, Case.Events.CURRENT_CASE,
Case.Events.DATA_SOURCE_NAME_CHANGED); Case.Events.DATA_SOURCE_NAME_CHANGED);
@ -90,7 +90,7 @@ final class CaseEventListener implements PropertyChangeListener {
if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) { if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
return; return;
} }
CentralRepository dbManager; CentralRepository dbManager;
try { try {
dbManager = CentralRepository.getInstance(); dbManager = CentralRepository.getInstance();
@ -98,7 +98,7 @@ final class CaseEventListener implements PropertyChangeListener {
LOGGER.log(Level.SEVERE, "Failed to get instance of db manager.", ex); LOGGER.log(Level.SEVERE, "Failed to get instance of db manager.", ex);
return; return;
} }
// If any changes are made to which event types are handled the change // If any changes are made to which event types are handled the change
// must also be made to CASE_EVENTS_OF_INTEREST. // must also be made to CASE_EVENTS_OF_INTEREST.
switch (Case.Events.valueOf(evt.getPropertyName())) { switch (Case.Events.valueOf(evt.getPropertyName())) {
@ -132,7 +132,7 @@ final class CaseEventListener implements PropertyChangeListener {
break; break;
} }
} }
/* /*
* Add all of our Case Event Listeners to the case. * Add all of our Case Event Listeners to the case.
*/ */
@ -147,6 +147,46 @@ final class CaseEventListener implements PropertyChangeListener {
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this); Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
} }
/**
* Returns true if the tag has a notable status.
*
* @param t The tag to use in determination.
*
* @return Whether or not it is a notable tag.
*/
private static boolean isNotableTag(Tag t) {
return (t != null && isNotableTagName(t.getName()));
}
/**
* Returns true if the tag name has a notable status.
*
* @param t The tag name to use in determination.
*
* @return Whether or not it is a notable tag name.
*/
private static boolean isNotableTagName(TagName t) {
return (t != null && TagsManager.getNotableTagDisplayNames().contains(t.getDisplayName()));
}
/**
* Searches a list of tags for a tag with a notable status.
*
* @param tags The tags to search.
*
* @return Whether or not the list contains a notable tag.
*/
private static boolean hasNotableTag(List<? extends Tag> tags) {
if (tags == null) {
return false;
}
return tags.stream()
.filter(CaseEventListener::isNotableTag)
.findFirst()
.isPresent();
}
private final class ContentTagTask implements Runnable { private final class ContentTagTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -163,72 +203,98 @@ final class CaseEventListener implements PropertyChangeListener {
return; return;
} }
AbstractFile af; Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
TskData.FileKnown knownStatus; if (curEventType == Case.Events.CONTENT_TAG_ADDED && event instanceof ContentTagAddedEvent) {
String comment; handleTagAdded((ContentTagAddedEvent) event);
if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.CONTENT_TAG_ADDED) { } else if (curEventType == Case.Events.CONTENT_TAG_DELETED && event instanceof ContentTagDeletedEvent) {
// For added tags, we want to change the known status to BAD if the handleTagDeleted((ContentTagDeletedEvent) event);
// tag that was just added is in the list of central repo tags. } else {
final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) event; LOGGER.log(Level.SEVERE,
final ContentTag tagAdded = tagAddedEvent.getAddedTag(); String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
event, curEventType));
}
}
if (TagsManager.getNotableTagDisplayNames().contains(tagAdded.getName().getDisplayName())) { private void handleTagDeleted(ContentTagDeletedEvent evt) {
if (tagAdded.getContent() instanceof AbstractFile) { // ensure tag deleted event has a valid content id
af = (AbstractFile) tagAdded.getContent(); if (evt.getDeletedTagInfo() == null) {
knownStatus = TskData.FileKnown.BAD; LOGGER.log(Level.SEVERE, "ContentTagDeletedEvent did not have valid content to provide a content id.");
comment = tagAdded.getComment(); return;
} else {
LOGGER.log(Level.WARNING, "Error updating non-file object");
return;
}
} else {
// The added tag isn't flagged as bad in central repo, so do nothing
return;
}
} else { // CONTENT_TAG_DELETED
// For deleted tags, we want to set the file status to UNKNOWN if:
// - The tag that was just removed is notable in central repo
// - There are no remaining tags that are notable
final ContentTagDeletedEvent tagDeletedEvent = (ContentTagDeletedEvent) event;
long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
if (!TagsManager.getNotableTagDisplayNames().contains(tagName)) {
// If the tag that got removed isn't on the list of central repo tags, do nothing
return;
}
try {
// Get the remaining tags on the content object
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(contentID);
TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
List<ContentTag> tags = tagsManager.getContentTagsByContent(content);
if (tags.stream()
.map(tag -> tag.getName().getDisplayName())
.filter(TagsManager.getNotableTagDisplayNames()::contains)
.collect(Collectors.toList())
.isEmpty()) {
// There are no more bad tags on the object
if (content instanceof AbstractFile) {
af = (AbstractFile) content;
knownStatus = TskData.FileKnown.UNKNOWN;
comment = "";
} else {
LOGGER.log(Level.WARNING, "Error updating non-file object");
return;
}
} else {
// There's still at least one bad tag, so leave the known status as is
return;
}
} catch (TskCoreException | NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Failed to find content", ex);
return;
}
} }
try {
// obtain content
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
if (content == null) {
LOGGER.log(Level.WARNING,
String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
return;
}
// then handle the event
handleTagChange(content);
} catch (NoCurrentCaseException | TskCoreException ex) {
LOGGER.log(Level.WARNING, "Error updating non-file object: " + evt.getDeletedTagInfo().getContentID(), ex);
}
}
private void handleTagAdded(ContentTagAddedEvent evt) {
// ensure tag added event has a valid content id
if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null) {
LOGGER.log(Level.SEVERE, "ContentTagAddedEvent did not have valid content to provide a content id.");
return;
}
// then handle the event
handleTagChange(evt.getAddedTag().getContent());
}
/**
* When a tag is added or deleted, check if there are other notable tags
* for the item. If there are, set known status as notable. If not set
* status as unknown.
*
* @param content The content for the tag that was added or deleted.
*/
private void handleTagChange(Content content) {
AbstractFile af = null;
try {
af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(content.getId());
} catch (NoCurrentCaseException | TskCoreException ex) {
Long contentID = (content != null) ? content.getId() : null;
LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, ex);
}
if (af == null) {
return;
}
try {
// Get the tags on the content object
TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
if (hasNotableTag(tagsManager.getContentTagsByContent(content))) {
// if there is a notable tag on the object, set content known status to bad
setContentKnownStatus(af, TskData.FileKnown.BAD);
} else {
// otherwise, set to unknown
setContentKnownStatus(af, TskData.FileKnown.UNKNOWN);
}
} catch (TskCoreException | NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
}
}
/**
* Sets the known status for the correlation attribute instance for the
* given abstract file.
*
* @param af The abstract file for which to set the correlation
* attribute instance.
* @param knownStatus The new known status for the correlation attribute
* instance.
*/
private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) {
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af); final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af);
if (eamArtifact != null) { if (eamArtifact != null) {
@ -239,7 +305,7 @@ final class CaseEventListener implements PropertyChangeListener {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
} }
} }
} // CONTENT_TAG_ADDED, CONTENT_TAG_DELETED }
} }
private final class BlackboardTagTask implements Runnable { private final class BlackboardTagTask implements Runnable {
@ -258,87 +324,125 @@ final class CaseEventListener implements PropertyChangeListener {
return; return;
} }
Content content; Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
BlackboardArtifact bbArtifact; if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED && event instanceof BlackBoardArtifactTagAddedEvent) {
TskData.FileKnown knownStatus; handleTagAdded((BlackBoardArtifactTagAddedEvent) event);
String comment; } else if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED && event instanceof BlackBoardArtifactTagDeletedEvent) {
if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED) { handleTagDeleted((BlackBoardArtifactTagDeletedEvent) event);
// For added tags, we want to change the known status to BAD if the } else {
// tag that was just added is in the list of central repo tags. LOGGER.log(Level.WARNING,
final BlackBoardArtifactTagAddedEvent tagAddedEvent = (BlackBoardArtifactTagAddedEvent) event; String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag(); event, curEventType));
if (TagsManager.getNotableTagDisplayNames().contains(tagAdded.getName().getDisplayName())) {
content = tagAdded.getContent();
bbArtifact = tagAdded.getArtifact();
knownStatus = TskData.FileKnown.BAD;
comment = tagAdded.getComment();
} else {
// The added tag isn't flagged as bad in central repo, so do nothing
return;
}
} else { //BLACKBOARD_ARTIFACT_TAG_DELETED
Case openCase;
try {
openCase = Case.getCurrentCaseThrows();
} catch (NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex);
return;
}
// For deleted tags, we want to set the file status to UNKNOWN if:
// - The tag that was just removed is notable in central repo
// - There are no remaining tags that are notable
final BlackBoardArtifactTagDeletedEvent tagDeletedEvent = (BlackBoardArtifactTagDeletedEvent) event;
long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID();
String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
if (!TagsManager.getNotableTagDisplayNames().contains(tagName)) {
// If the tag that got removed isn't on the list of central repo tags, do nothing
return;
}
try {
// Get the remaining tags on the artifact
content = openCase.getSleuthkitCase().getContentById(contentID);
bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(artifactID);
TagsManager tagsManager = openCase.getServices().getTagsManager();
List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
if (tags.stream()
.map(tag -> tag.getName().getDisplayName())
.filter(TagsManager.getNotableTagDisplayNames()::contains)
.collect(Collectors.toList())
.isEmpty()) {
// There are no more bad tags on the object
knownStatus = TskData.FileKnown.UNKNOWN;
comment = "";
} else {
// There's still at least one bad tag, so leave the known status as is
return;
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to find content", ex);
return;
}
} }
}
if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) { private void handleTagDeleted(BlackBoardArtifactTagDeletedEvent evt) {
// ensure tag deleted event has a valid content id
if (evt.getDeletedTagInfo() == null) {
LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagDeletedEvent did not have valid content to provide a content id.");
return; return;
} }
try {
Case openCase = Case.getCurrentCaseThrows();
// obtain content
Content content = openCase.getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
if (content == null) {
LOGGER.log(Level.WARNING,
String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
return;
}
// obtain blackboard artifact
BlackboardArtifact bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(evt.getDeletedTagInfo().getArtifactID());
if (bbArtifact == null) {
LOGGER.log(Level.WARNING,
String.format("Unable to get blackboard artifact for item with artifact id: %d.", evt.getDeletedTagInfo().getArtifactID()));
return;
}
// then handle the event
handleTagChange(content, bbArtifact);
} catch (NoCurrentCaseException | TskCoreException ex) {
LOGGER.log(Level.WARNING, "Error updating non-file object.", ex);
}
}
private void handleTagAdded(BlackBoardArtifactTagAddedEvent evt) {
// ensure tag added event has a valid content id
if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null || evt.getAddedTag().getArtifact() == null) {
LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagAddedEvent did not have valid content to provide a content id.");
return;
}
// then handle the event
handleTagChange(evt.getAddedTag().getContent(), evt.getAddedTag().getArtifact());
}
/**
* When a tag is added or deleted, check if there are other notable tags
* for the item. If there are, set known status as notable. If not set
* status as unknown.
*
* @param content The content for the tag that was added or deleted.
* @param bbArtifact The artifact for the tag that was added or deleted.
*/
private void handleTagChange(Content content, BlackboardArtifact bbArtifact) {
Case openCase;
try {
openCase = Case.getCurrentCaseThrows();
} catch (NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex);
return;
}
try {
if (isKnownFile(content)) {
return;
}
TagsManager tagsManager = openCase.getServices().getTagsManager();
List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
if (hasNotableTag(tags)) {
setArtifactKnownStatus(bbArtifact, TskData.FileKnown.BAD);
} else {
setArtifactKnownStatus(bbArtifact, TskData.FileKnown.UNKNOWN);
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
return;
}
}
/**
* Determines if the content is an abstract file and is a known file.
*
* @param content The content to assess.
*
* @return True if an abstract file and a known file.
*/
private boolean isKnownFile(Content content) {
return ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN));
}
/**
* Sets the known status of a blackboard artifact in the central
* repository.
*
* @param bbArtifact The blackboard artifact to set known status.
* @param knownStatus The new known status.
*/
private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) {
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact);
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) {
eamArtifact.setComment(comment);
try { try {
dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus); dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus);
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
} }
} }
} // BLACKBOARD_ARTIFACT_TAG_ADDED, BLACKBOARD_ARTIFACT_TAG_DELETED }
} }
@ -439,8 +543,8 @@ final class CaseEventListener implements PropertyChangeListener {
//if the file will have no tags with a status which would prevent the current status from being changed //if the file will have no tags with a status which would prevent the current status from being changed
if (!hasTagWithConflictingKnownStatus) { if (!hasTagWithConflictingKnownStatus) {
Content taggedContent = contentTag.getContent(); Content taggedContent = contentTag.getContent();
if (taggedContent instanceof AbstractFile) { if (taggedContent instanceof AbstractFile) {
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile)taggedContent); final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile) taggedContent);
if (eamArtifact != null) { if (eamArtifact != null) {
CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus());
} }