19 package org.sleuthkit.autopsy.centralrepository.datamodel;
21 import com.google.common.cache.Cache;
22 import com.google.common.cache.CacheBuilder;
23 import com.google.common.cache.CacheLoader;
24 import java.net.UnknownHostException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Collection;
28 import java.util.LinkedHashSet;
29 import java.util.stream.Collectors;
30 import java.sql.Connection;
31 import java.sql.PreparedStatement;
32 import java.sql.ResultSet;
33 import java.sql.SQLException;
34 import java.sql.Statement;
35 import java.sql.Types;
36 import java.time.LocalDate;
37 import java.util.HashMap;
40 import java.util.concurrent.ExecutionException;
41 import java.util.concurrent.TimeUnit;
42 import java.util.logging.Level;
48 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
56 abstract class AbstractSqlEamDb
implements EamDb {
62 private int bulkArtifactsCount;
63 protected int bulkArtifactsThreshold;
64 private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
65 private static final int CASE_CACHE_TIMEOUT = 5;
66 private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
68 private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
69 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
71 private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
72 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
74 private static final Cache<String, CorrelationDataSource> dataSourceCacheByDeviceId = CacheBuilder.newBuilder()
75 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
77 private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
78 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
81 static final int MAX_VALUE_LENGTH = 256;
85 static final int DEFAULT_BULK_THRESHHOLD = 1000;
93 bulkArtifactsCount = 0;
94 bulkArtifacts =
new HashMap<>();
97 defaultCorrelationTypes.forEach((type) -> {
98 bulkArtifacts.put(type.getDbTableName(),
new ArrayList<>());
116 public void newDbInfo(String name, String value)
throws EamDbException {
117 Connection conn = connect();
119 PreparedStatement preparedStatement = null;
120 String sql =
"INSERT INTO db_info (name, value) VALUES (?, ?) "
121 + getConflictClause();
123 preparedStatement = conn.prepareStatement(sql);
124 preparedStatement.setString(1, name);
125 preparedStatement.setString(2, value);
126 preparedStatement.executeUpdate();
127 }
catch (SQLException ex) {
128 throw new EamDbException(
"Error adding new name/value pair to db_info.", ex);
146 public String getDbInfo(String name)
throws EamDbException {
147 Connection conn = connect();
149 PreparedStatement preparedStatement = null;
150 ResultSet resultSet = null;
152 String sql =
"SELECT value FROM db_info WHERE name=?";
154 preparedStatement = conn.prepareStatement(sql);
155 preparedStatement.setString(1, name);
156 resultSet = preparedStatement.executeQuery();
157 if (resultSet.next()) {
158 value = resultSet.getString(
"value");
160 }
catch (SQLException ex) {
161 throw new EamDbException(
"Error getting value for name.", ex);
174 protected final void clearCaches() {
175 typeCache.invalidateAll();
176 caseCacheByUUID.invalidateAll();
177 caseCacheById.invalidateAll();
178 dataSourceCacheByDeviceId.invalidateAll();
179 dataSourceCacheById.invalidateAll();
191 public void updateDbInfo(String name, String value)
throws EamDbException {
192 Connection conn = connect();
194 PreparedStatement preparedStatement = null;
195 String sql =
"UPDATE db_info SET value=? WHERE name=?";
197 preparedStatement = conn.prepareStatement(sql);
198 preparedStatement.setString(1, value);
199 preparedStatement.setString(2, name);
200 preparedStatement.executeUpdate();
201 }
catch (SQLException ex) {
202 throw new EamDbException(
"Error updating value for name.", ex);
223 if (cRCase != null) {
227 Connection conn = connect();
228 PreparedStatement preparedStatement = null;
230 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
231 +
"examiner_name, examiner_email, examiner_phone, notes) "
232 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
233 + getConflictClause();
234 ResultSet resultSet = null;
236 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
238 preparedStatement.setString(1, eamCase.
getCaseUUID());
239 if (null == eamCase.
getOrg()) {
240 preparedStatement.setNull(2, Types.INTEGER);
247 preparedStatement.setNull(5, Types.INTEGER);
252 preparedStatement.setNull(6, Types.INTEGER);
257 preparedStatement.setNull(7, Types.INTEGER);
262 preparedStatement.setNull(8, Types.INTEGER);
266 if (
"".equals(eamCase.
getNotes())) {
267 preparedStatement.setNull(9, Types.INTEGER);
269 preparedStatement.setString(9, eamCase.
getNotes());
272 preparedStatement.executeUpdate();
274 resultSet = preparedStatement.getGeneratedKeys();
275 if (!resultSet.next()) {
276 throw new EamDbException(String.format(
"Failed to INSERT case %s in central repo", eamCase.
getCaseUUID()));
278 int caseID = resultSet.getInt(1);
282 caseCacheByUUID.put(eamCase.
getCaseUUID(), correlationCase);
283 caseCacheById.put(caseID, correlationCase);
284 }
catch (SQLException ex) {
285 throw new EamDbException(
"Error inserting new case.", ex);
303 if (autopsyCase == null) {
304 throw new EamDbException(
"Case is null");
318 return newCase(curCeCase);
323 return getCaseByUUID(autopsyCase.
getName());
332 public void updateCase(
CorrelationCase eamCase)
throws EamDbException {
333 if (eamCase == null) {
334 throw new EamDbException(
"Correlation case is null");
337 Connection conn = connect();
339 PreparedStatement preparedStatement = null;
340 String sql =
"UPDATE cases "
341 +
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
342 +
"WHERE case_uid=?";
345 preparedStatement = conn.prepareStatement(sql);
347 if (null == eamCase.
getOrg()) {
348 preparedStatement.setNull(1, Types.INTEGER);
356 preparedStatement.setNull(4, Types.INTEGER);
361 preparedStatement.setNull(5, Types.INTEGER);
366 preparedStatement.setNull(6, Types.INTEGER);
371 preparedStatement.setNull(7, Types.INTEGER);
375 if (
"".equals(eamCase.
getNotes())) {
376 preparedStatement.setNull(8, Types.INTEGER);
378 preparedStatement.setString(8, eamCase.
getNotes());
381 preparedStatement.setString(9, eamCase.
getCaseUUID());
383 preparedStatement.executeUpdate();
385 caseCacheById.put(eamCase.
getID(), eamCase);
386 caseCacheByUUID.put(eamCase.
getCaseUUID(), eamCase);
387 }
catch (SQLException ex) {
388 throw new EamDbException(
"Error updating case.", ex);
403 public CorrelationCase getCaseByUUID(String caseUUID)
throws EamDbException {
405 return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
406 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
409 }
catch (ExecutionException ex) {
410 throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
421 private CorrelationCase getCaseByUUIDFromCr(String caseUUID)
throws EamDbException {
422 Connection conn = connect();
425 PreparedStatement preparedStatement = null;
426 ResultSet resultSet = null;
428 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
429 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
431 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
432 +
"WHERE case_uid=?";
435 preparedStatement = conn.prepareStatement(sql);
436 preparedStatement.setString(1, caseUUID);
437 resultSet = preparedStatement.executeQuery();
438 if (resultSet.next()) {
439 eamCaseResult = getEamCaseFromResultSet(resultSet);
441 if (eamCaseResult != null) {
443 caseCacheById.put(eamCaseResult.
getID(), eamCaseResult);
445 }
catch (SQLException ex) {
446 throw new EamDbException(
"Error getting case details.", ex);
453 return eamCaseResult;
466 return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
467 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
470 }
catch (ExecutionException ex) {
471 throw new EamDbException(
"Error getting autopsy case from Central repo", ex);
482 private CorrelationCase getCaseByIdFromCr(
int caseId)
throws EamDbException {
483 Connection conn = connect();
486 PreparedStatement preparedStatement = null;
487 ResultSet resultSet = null;
489 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
490 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
492 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
493 +
"WHERE cases.id=?";
495 preparedStatement = conn.prepareStatement(sql);
496 preparedStatement.setInt(1, caseId);
497 resultSet = preparedStatement.executeQuery();
498 if (resultSet.next()) {
499 eamCaseResult = getEamCaseFromResultSet(resultSet);
501 if (eamCaseResult != null) {
503 caseCacheByUUID.put(eamCaseResult.
getCaseUUID(), eamCaseResult);
505 }
catch (SQLException ex) {
506 throw new EamDbException(
"Error getting case details.", ex);
513 return eamCaseResult;
522 public List<CorrelationCase> getCases()
throws EamDbException {
523 Connection conn = connect();
525 List<CorrelationCase> cases =
new ArrayList<>();
527 PreparedStatement preparedStatement = null;
528 ResultSet resultSet = null;
530 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
531 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
533 +
"LEFT JOIN organizations ON cases.org_id=organizations.id";
536 preparedStatement = conn.prepareStatement(sql);
537 resultSet = preparedStatement.executeQuery();
538 while (resultSet.next()) {
539 eamCaseResult = getEamCaseFromResultSet(resultSet);
540 cases.add(eamCaseResult);
542 }
catch (SQLException ex) {
543 throw new EamDbException(
"Error getting all cases.", ex);
562 private static String getDataSourceByDeviceIdCacheKey(
int caseId, String dataSourceDeviceId) {
563 return "Case" + caseId +
"DeviceId" + dataSourceDeviceId;
575 private static String getDataSourceByIdCacheKey(
int caseId,
int dataSourceId) {
576 return "Case" + caseId +
"Id" + dataSourceId;
587 throw new EamDbException(
"Case ID is -1");
588 }
else if (eamDataSource.getID() != -1) {
592 Connection conn = connect();
594 PreparedStatement preparedStatement = null;
596 String sql =
"INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) "
597 + getConflictClause();
598 ResultSet resultSet = null;
600 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
602 preparedStatement.setString(1, eamDataSource.
getDeviceID());
603 preparedStatement.setInt(2, eamDataSource.
getCaseID());
604 preparedStatement.setString(3, eamDataSource.
getName());
606 preparedStatement.executeUpdate();
607 resultSet = preparedStatement.getGeneratedKeys();
608 if (!resultSet.next()) {
609 throw new EamDbException(String.format(
"Failed to INSERT data source %s in central repo", eamDataSource.
getName()));
611 int dataSourceId = resultSet.getInt(1);
613 dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.
getCaseID(), dataSource.
getDeviceID()), dataSource);
614 dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.
getCaseID(), dataSource.getID()), dataSource);
615 }
catch (SQLException ex) {
616 throw new EamDbException(
"Error inserting new data source.", ex);
638 if (correlationCase == null) {
639 throw new EamDbException(
"Correlation case is null");
642 return dataSourceCacheByDeviceId.get(getDataSourceByDeviceIdCacheKey(correlationCase.
getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId));
643 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
646 }
catch (ExecutionException ex) {
647 throw new EamDbException(
"Error getting data source from central repository", ex);
664 Connection conn = connect();
667 PreparedStatement preparedStatement = null;
668 ResultSet resultSet = null;
670 String sql =
"SELECT * FROM data_sources WHERE device_id=? AND case_id=?";
673 preparedStatement = conn.prepareStatement(sql);
674 preparedStatement.setString(1, dataSourceDeviceId);
675 preparedStatement.setInt(2, correlationCase.
getID());
676 resultSet = preparedStatement.executeQuery();
677 if (resultSet.next()) {
678 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
680 if (eamDataSourceResult != null) {
681 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCase.
getID(), eamDataSourceResult.getID()), eamDataSourceResult);
683 }
catch (SQLException ex) {
684 throw new EamDbException(
"Error getting data source.", ex);
691 return eamDataSourceResult;
705 if (correlationCase == null) {
706 throw new EamDbException(
"Correlation case is null");
709 return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.
getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
710 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
713 }
catch (ExecutionException ex) {
714 throw new EamDbException(
"Error getting data source from central repository", ex);
728 Connection conn = connect();
731 PreparedStatement preparedStatement = null;
732 ResultSet resultSet = null;
734 String sql =
"SELECT * FROM data_sources WHERE id=? AND case_id=?";
737 preparedStatement = conn.prepareStatement(sql);
738 preparedStatement.setInt(1, dataSourceId);
739 preparedStatement.setInt(2, correlationCase.
getID());
740 resultSet = preparedStatement.executeQuery();
741 if (resultSet.next()) {
742 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
744 if (eamDataSourceResult != null) {
745 dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(correlationCase.
getID(), eamDataSourceResult.
getDeviceID()), eamDataSourceResult);
747 }
catch (SQLException ex) {
748 throw new EamDbException(
"Error getting data source.", ex);
755 return eamDataSourceResult;
764 public List<CorrelationDataSource> getDataSources()
throws EamDbException {
765 Connection conn = connect();
767 List<CorrelationDataSource> dataSources =
new ArrayList<>();
769 PreparedStatement preparedStatement = null;
770 ResultSet resultSet = null;
772 String sql =
"SELECT * FROM data_sources";
775 preparedStatement = conn.prepareStatement(sql);
776 resultSet = preparedStatement.executeQuery();
777 while (resultSet.next()) {
778 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
779 dataSources.add(eamDataSourceResult);
781 }
catch (SQLException ex) {
782 throw new EamDbException(
"Error getting all data sources.", ex);
800 checkAddArtifactInstanceNulls(eamArtifact);
802 Connection conn = connect();
804 PreparedStatement preparedStatement = null;
811 +
"(case_id, data_source_id, value, file_path, known_status, comment) "
812 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
813 +
"(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) "
814 + getConflictClause();
817 preparedStatement = conn.prepareStatement(sql);
825 preparedStatement.setString(5, eamArtifact.
getFilePath().toLowerCase());
826 preparedStatement.setByte(6, eamArtifact.
getKnownStatus().getFileKnownValue());
828 preparedStatement.setNull(7, Types.INTEGER);
830 preparedStatement.setString(7, eamArtifact.
getComment());
833 preparedStatement.executeUpdate();
836 }
catch (SQLException ex) {
837 throw new EamDbException(
"Error inserting new artifact into artifacts table.", ex);
845 if (eamArtifact == null) {
846 throw new EamDbException(
"CorrelationAttribute is null");
849 throw new EamDbException(
"Correlation type is null");
852 throw new EamDbException(
"Correlation value is null");
855 throw new EamDbException(
"Artifact value too long for central repository."
856 +
"\nCorrelationArtifact ID: " + eamArtifact.
getID()
862 throw new EamDbException(
"CorrelationAttributeInstance case is null");
865 throw new EamDbException(
"CorrelationAttributeInstance data source is null");
868 throw new EamDbException(
"CorrelationAttributeInstance known status is null");
888 Connection conn = connect();
890 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
893 PreparedStatement preparedStatement = null;
894 ResultSet resultSet = null;
903 +
" cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM "
905 +
" LEFT JOIN cases ON "
907 +
".case_id=cases.id"
908 +
" LEFT JOIN data_sources ON "
910 +
".data_source_id=data_sources.id"
914 preparedStatement = conn.prepareStatement(sql);
915 preparedStatement.setString(1, normalizedValue);
916 resultSet = preparedStatement.executeQuery();
917 while (resultSet.next()) {
918 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
919 artifactInstances.add(artifactInstance);
921 }
catch (SQLException ex) {
922 throw new EamDbException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
929 return artifactInstances;
946 throw new EamDbException(
"Correlation type is null");
948 if (filePath == null) {
949 throw new EamDbException(
"Correlation value is null");
951 Connection conn = connect();
953 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
956 PreparedStatement preparedStatement = null;
957 ResultSet resultSet = null;
966 +
" cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM "
968 +
" LEFT JOIN cases ON "
970 +
".case_id=cases.id"
971 +
" LEFT JOIN data_sources ON "
973 +
".data_source_id=data_sources.id"
974 +
" WHERE file_path=?";
977 preparedStatement = conn.prepareStatement(sql);
978 preparedStatement.setString(1, filePath.toLowerCase());
979 resultSet = preparedStatement.executeQuery();
980 while (resultSet.next()) {
982 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
983 artifactInstances.add(artifactInstance);
985 logger.log(Level.INFO,
"Unable to get artifact instance from resultset.", ex);
988 }
catch (SQLException ex) {
989 throw new EamDbException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
996 return artifactInstances;
1013 Connection conn = connect();
1015 Long instanceCount = 0L;
1016 PreparedStatement preparedStatement = null;
1017 ResultSet resultSet = null;
1021 =
"SELECT count(*) FROM "
1026 preparedStatement = conn.prepareStatement(sql);
1027 preparedStatement.setString(1, normalizedValue);
1028 resultSet = preparedStatement.executeQuery();
1030 instanceCount = resultSet.getLong(1);
1031 }
catch (SQLException ex) {
1032 throw new EamDbException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1039 return instanceCount;
1044 if (corAttr == null) {
1045 throw new EamDbException(
"CorrelationAttribute is null");
1048 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1049 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1050 return commonalityPercentage.intValue();
1067 Connection conn = connect();
1069 Long instanceCount = 0L;
1070 PreparedStatement preparedStatement = null;
1071 ResultSet resultSet = null;
1075 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1077 +
" WHERE value=?) AS "
1079 +
"_distinct_case_data_source_tuple";
1082 preparedStatement = conn.prepareStatement(sql);
1083 preparedStatement.setString(1, normalizedValue);
1084 resultSet = preparedStatement.executeQuery();
1086 instanceCount = resultSet.getLong(1);
1087 }
catch (SQLException ex) {
1088 throw new EamDbException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1095 return instanceCount;
1099 public Long getCountUniqueDataSources()
throws EamDbException {
1100 Connection conn = connect();
1102 Long instanceCount = 0L;
1103 PreparedStatement preparedStatement = null;
1104 ResultSet resultSet = null;
1106 String stmt =
"SELECT count(*) FROM data_sources";
1109 preparedStatement = conn.prepareStatement(stmt);
1110 resultSet = preparedStatement.executeQuery();
1112 instanceCount = resultSet.getLong(1);
1113 }
catch (SQLException ex) {
1114 throw new EamDbException(
"Error counting data sources.", ex);
1121 return instanceCount;
1136 public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID)
throws EamDbException {
1137 Connection conn = connect();
1139 Long instanceCount = 0L;
1141 PreparedStatement preparedStatement = null;
1142 ResultSet resultSet = null;
1145 String sql =
"SELECT 0 ";
1151 +=
"+ (SELECT count(*) FROM "
1153 +
" WHERE data_source_id=(SELECT data_sources.id FROM cases INNER JOIN data_sources ON cases.id = data_sources.case_id WHERE case_uid=? and device_id=?))";
1157 preparedStatement = conn.prepareStatement(sql);
1159 for (
int i = 0; i < artifactTypes.size(); ++i) {
1160 preparedStatement.setString(2 * i + 1, caseUUID);
1161 preparedStatement.setString(2 * i + 2, dataSourceID);
1164 resultSet = preparedStatement.executeQuery();
1166 instanceCount = resultSet.getLong(1);
1167 }
catch (SQLException ex) {
1168 throw new EamDbException(
"Error counting artifact instances by caseName/dataSource.", ex);
1175 return instanceCount;
1189 throw new EamDbException(
"Correlation type is null");
1192 synchronized (bulkArtifacts) {
1194 bulkArtifactsCount++;
1196 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1197 commitAttributeInstancesBulk();
1207 protected abstract String getConflictClause();
1214 public void commitAttributeInstancesBulk()
throws EamDbException {
1217 Connection conn = connect();
1218 PreparedStatement bulkPs = null;
1221 synchronized (bulkArtifacts) {
1222 if (bulkArtifactsCount == 0) {
1232 +
" (case_id, data_source_id, value, file_path, known_status, comment) "
1233 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1234 +
"(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) "
1235 + getConflictClause();
1237 bulkPs = conn.prepareStatement(sql);
1239 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(type.getDbTableName());
1245 throw new EamDbException(
"CorrelationAttributeInstance case is null for: "
1246 +
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
1251 throw new EamDbException(
"CorrelationAttributeInstance data source is null for: "
1252 +
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
1257 throw new EamDbException(
"CorrelationAttributeInstance known status is null for: "
1258 +
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
1261 +
"\n\tEam Instance: "
1272 bulkPs.setByte(6, eamArtifact.
getKnownStatus().getFileKnownValue());
1274 bulkPs.setNull(7, Types.INTEGER);
1276 bulkPs.setString(7, eamArtifact.
getComment());
1280 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1281 +
"\n\tCorrelationArtifact ID: " + eamArtifact.
getID()
1284 +
"\n\tEam Instance: "
1287 +
"\n\t\tFilePath: " + eamArtifact.
getFilePath());
1293 bulkPs.executeBatch();
1294 bulkArtifacts.get(type.getDbTableName()).clear();
1301 bulkArtifactsCount = 0;
1303 }
catch (SQLException ex) {
1304 throw new EamDbException(
"Error inserting bulk artifacts.", ex);
1315 public void bulkInsertCases(List<CorrelationCase> cases)
throws EamDbException {
1316 if (cases == null) {
1317 throw new EamDbException(
"cases argument is null");
1320 if (cases.isEmpty()) {
1324 Connection conn = connect();
1327 PreparedStatement bulkPs = null;
1329 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1330 +
"examiner_name, examiner_email, examiner_phone, notes) "
1331 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1332 + getConflictClause();
1333 bulkPs = conn.prepareStatement(sql);
1337 if (null == eamCase.
getOrg()) {
1338 bulkPs.setNull(2, Types.INTEGER);
1346 bulkPs.setNull(5, Types.INTEGER);
1351 bulkPs.setNull(6, Types.INTEGER);
1356 bulkPs.setNull(7, Types.INTEGER);
1361 bulkPs.setNull(8, Types.INTEGER);
1365 if (
"".equals(eamCase.
getNotes())) {
1366 bulkPs.setNull(9, Types.INTEGER);
1368 bulkPs.setString(9, eamCase.
getNotes());
1376 if (counter >= bulkArtifactsThreshold) {
1377 bulkPs.executeBatch();
1382 bulkPs.executeBatch();
1383 }
catch (SQLException ex) {
1384 throw new EamDbException(
"Error inserting bulk cases.", ex);
1403 if (eamArtifact == null) {
1404 throw new EamDbException(
"CorrelationAttributeInstance is null");
1407 throw new EamDbException(
"Correlation case is null");
1410 throw new EamDbException(
"Correlation data source is null");
1413 Connection conn = connect();
1414 PreparedStatement preparedQuery = null;
1421 +
"WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) "
1422 +
"AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) "
1424 +
"AND file_path=?";
1427 preparedQuery = conn.prepareStatement(sqlUpdate);
1428 preparedQuery.setString(1, eamArtifact.
getComment());
1432 preparedQuery.setString(5, eamArtifact.
getFilePath().toLowerCase());
1433 preparedQuery.executeUpdate();
1434 }
catch (SQLException ex) {
1435 throw new EamDbException(
"Error getting/setting artifact instance comment=" + eamArtifact.
getComment(), ex);
1460 if (correlationCase == null) {
1461 throw new EamDbException(
"Correlation case is null");
1463 if (correlationDataSource == null) {
1464 throw new EamDbException(
"Correlation data source is null");
1466 if (filePath == null) {
1467 throw new EamDbException(
"Correlation file path is null");
1470 Connection conn = connect();
1472 PreparedStatement preparedStatement = null;
1473 ResultSet resultSet = null;
1481 =
"SELECT id, known_status, comment FROM "
1483 +
" WHERE case_id=?"
1484 +
" AND data_source_id=?"
1486 +
" AND file_path=?";
1488 preparedStatement = conn.prepareStatement(sql);
1489 preparedStatement.setInt(1, correlationCase.
getID());
1490 preparedStatement.setInt(2, correlationDataSource.getID());
1491 preparedStatement.setString(3, normalizedValue);
1492 preparedStatement.setString(4, filePath.toLowerCase());
1493 resultSet = preparedStatement.executeQuery();
1494 if (resultSet.next()) {
1495 int instanceId = resultSet.getInt(1);
1496 int knownStatus = resultSet.getInt(2);
1497 String comment = resultSet.getString(3);
1500 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus));
1502 }
catch (SQLException ex) {
1503 throw new EamDbException(
"Error getting notable artifact instances.", ex);
1510 return correlationAttributeInstance;
1524 public void setAttributeInstanceKnownStatus(
CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus)
throws EamDbException {
1525 if (eamArtifact == null) {
1526 throw new EamDbException(
"CorrelationAttribute is null");
1528 if (knownStatus == null) {
1529 throw new EamDbException(
"Known status is null");
1533 throw new EamDbException(
"Correlation case is null");
1536 throw new EamDbException(
"Correlation data source is null");
1539 Connection conn = connect();
1541 PreparedStatement preparedUpdate = null;
1542 PreparedStatement preparedQuery = null;
1543 ResultSet resultSet = null;
1550 +
" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) "
1551 +
"AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) "
1553 +
"AND file_path=?";
1558 +
" SET known_status=?, comment=? "
1562 preparedQuery = conn.prepareStatement(sqlQuery);
1566 preparedQuery.setString(4, eamArtifact.
getFilePath());
1567 resultSet = preparedQuery.executeQuery();
1568 if (resultSet.next()) {
1569 int instance_id = resultSet.getInt(
"id");
1570 preparedUpdate = conn.prepareStatement(sqlUpdate);
1572 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
1577 preparedUpdate.setNull(2, Types.INTEGER);
1579 preparedUpdate.setString(2, eamArtifact.
getComment());
1581 preparedUpdate.setInt(3, instance_id);
1583 preparedUpdate.executeUpdate();
1591 if (null == correlationCaseWithId) {
1599 addArtifactInstance(eamArtifact);
1602 }
catch (SQLException ex) {
1603 throw new EamDbException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
1625 Connection conn = connect();
1627 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1630 PreparedStatement preparedStatement = null;
1631 ResultSet resultSet = null;
1640 +
"cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM "
1642 +
" LEFT JOIN cases ON "
1644 +
".case_id=cases.id"
1645 +
" LEFT JOIN data_sources ON "
1647 +
".data_source_id=data_sources.id"
1648 +
" WHERE value=? AND known_status=?";
1651 preparedStatement = conn.prepareStatement(sql);
1652 preparedStatement.setString(1, normalizedValue);
1653 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1654 resultSet = preparedStatement.executeQuery();
1655 while (resultSet.next()) {
1656 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1657 artifactInstances.add(artifactInstance);
1659 }
catch (SQLException ex) {
1660 throw new EamDbException(
"Error getting notable artifact instances.", ex);
1667 return artifactInstances;
1683 if (aType == null) {
1684 throw new EamDbException(
"Correlation type is null");
1687 Connection conn = connect();
1689 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1692 PreparedStatement preparedStatement = null;
1693 ResultSet resultSet = null;
1697 =
"SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value FROM "
1699 +
" LEFT JOIN cases ON "
1701 +
".case_id=cases.id"
1702 +
" LEFT JOIN data_sources ON "
1704 +
".data_source_id=data_sources.id"
1705 +
" WHERE known_status=?"
1711 preparedStatement = conn.prepareStatement(sql);
1712 preparedStatement.setByte(1, TskData.FileKnown.BAD.getFileKnownValue());
1713 resultSet = preparedStatement.executeQuery();
1714 while (resultSet.next()) {
1716 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1717 artifactInstances.add(artifactInstance);
1719 logger.log(Level.INFO,
"Unable to get artifact instance from resultset.", ex);
1722 }
catch (SQLException ex) {
1723 throw new EamDbException(
"Error getting notable artifact instances.", ex);
1730 return artifactInstances;
1746 Connection conn = connect();
1748 Long badInstances = 0L;
1749 PreparedStatement preparedStatement = null;
1750 ResultSet resultSet = null;
1754 =
"SELECT count(*) FROM "
1756 +
" WHERE value=? AND known_status=?";
1759 preparedStatement = conn.prepareStatement(sql);
1760 preparedStatement.setString(1, normalizedValue);
1761 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1762 resultSet = preparedStatement.executeQuery();
1764 badInstances = resultSet.getLong(1);
1765 }
catch (SQLException ex) {
1766 throw new EamDbException(
"Error getting count of notable artifact instances.", ex);
1773 return badInstances;
1793 Connection conn = connect();
1795 Collection<String> caseNames =
new LinkedHashSet<>();
1797 PreparedStatement preparedStatement = null;
1798 ResultSet resultSet = null;
1802 =
"SELECT DISTINCT case_name FROM "
1804 +
" INNER JOIN cases ON "
1806 +
".case_id=cases.id WHERE "
1810 +
".known_status=?";
1813 preparedStatement = conn.prepareStatement(sql);
1814 preparedStatement.setString(1, normalizedValue);
1815 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
1816 resultSet = preparedStatement.executeQuery();
1817 while (resultSet.next()) {
1818 caseNames.add(resultSet.getString(
"case_name"));
1820 }
catch (SQLException ex) {
1821 throw new EamDbException(
"Error getting notable artifact instances.", ex);
1828 return caseNames.stream().collect(Collectors.toList());
1839 public void deleteReferenceSet(
int referenceSetID)
throws EamDbException {
1840 deleteReferenceSetEntries(referenceSetID);
1841 deleteReferenceSetEntry(referenceSetID);
1851 private void deleteReferenceSetEntry(
int referenceSetID)
throws EamDbException {
1852 Connection conn = connect();
1854 PreparedStatement preparedStatement = null;
1855 String sql =
"DELETE FROM reference_sets WHERE id=?";
1858 preparedStatement = conn.prepareStatement(sql);
1859 preparedStatement.setInt(1, referenceSetID);
1860 preparedStatement.executeUpdate();
1861 }
catch (SQLException ex) {
1862 throw new EamDbException(
"Error deleting reference set " + referenceSetID, ex);
1877 private void deleteReferenceSetEntries(
int referenceSetID)
throws EamDbException {
1878 Connection conn = connect();
1880 PreparedStatement preparedStatement = null;
1881 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
1887 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1888 preparedStatement.setInt(1, referenceSetID);
1889 preparedStatement.executeUpdate();
1890 }
catch (SQLException ex) {
1891 throw new EamDbException(
"Error deleting files from reference set " + referenceSetID, ex);
1912 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws EamDbException {
1913 EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
1914 if (refSet == null) {
1951 Connection conn = connect();
1953 Long matchingInstances = 0L;
1954 PreparedStatement preparedStatement = null;
1955 ResultSet resultSet = null;
1956 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
1961 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
1962 preparedStatement.setString(1, normalizeValued);
1963 preparedStatement.setInt(2, referenceSetID);
1964 resultSet = preparedStatement.executeQuery();
1966 matchingInstances = resultSet.getLong(1);
1967 }
catch (SQLException ex) {
1968 throw new EamDbException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
1975 return 0 < matchingInstances;
1997 Connection conn = connect();
1999 Long badInstances = 0L;
2000 PreparedStatement preparedStatement = null;
2001 ResultSet resultSet = null;
2002 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2006 preparedStatement.setString(1, normalizeValued);
2007 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2008 resultSet = preparedStatement.executeQuery();
2010 badInstances = resultSet.getLong(1);
2011 }
catch (SQLException ex) {
2012 throw new EamDbException(
"Error determining if artifact is notable by reference.", ex);
2019 return 0 < badInstances;
2033 throw new EamDbException(
"Correlation type is null");
2036 if (instanceTableCallback == null) {
2037 throw new EamDbException(
"Callback interface is null");
2040 Connection conn = connect();
2041 PreparedStatement preparedStatement = null;
2042 ResultSet resultSet = null;
2044 StringBuilder sql =
new StringBuilder();
2045 sql.append(
"select * from ");
2046 sql.append(tableName);
2049 preparedStatement = conn.prepareStatement(sql.toString());
2050 resultSet = preparedStatement.executeQuery();
2051 instanceTableCallback.
process(resultSet);
2052 }
catch (SQLException ex) {
2053 throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
2073 throw new EamDbException(
"Correlation type is null");
2076 if (instanceTableCallback == null) {
2077 throw new EamDbException(
"Callback interface is null");
2080 if (whereClause == null) {
2081 throw new EamDbException(
"Where clause is null");
2084 Connection conn = connect();
2085 PreparedStatement preparedStatement = null;
2086 ResultSet resultSet = null;
2088 StringBuilder sql =
new StringBuilder(300);
2089 sql.append(
"select * from ")
2092 .append(whereClause);
2095 preparedStatement = conn.prepareStatement(sql.toString());
2096 resultSet = preparedStatement.executeQuery();
2097 instanceTableCallback.
process(resultSet);
2098 }
catch (SQLException ex) {
2099 throw new EamDbException(
"Error getting all artifact instances from instances table", ex);
2109 if (eamOrg == null) {
2110 throw new EamDbException(
"EamOrganization is null");
2111 }
else if (eamOrg.
getOrgID() != -1) {
2112 throw new EamDbException(
"EamOrganization already has an ID");
2115 Connection conn = connect();
2116 ResultSet generatedKeys = null;
2117 PreparedStatement preparedStatement = null;
2118 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2119 + getConflictClause();
2122 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2123 preparedStatement.setString(1, eamOrg.
getName());
2124 preparedStatement.setString(2, eamOrg.
getPocName());
2125 preparedStatement.setString(3, eamOrg.
getPocEmail());
2126 preparedStatement.setString(4, eamOrg.
getPocPhone());
2128 preparedStatement.executeUpdate();
2129 generatedKeys = preparedStatement.getGeneratedKeys();
2130 if (generatedKeys.next()) {
2131 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2134 throw new SQLException(
"Creating user failed, no ID obtained.");
2136 }
catch (SQLException ex) {
2137 throw new EamDbException(
"Error inserting new organization.", ex);
2153 public List<EamOrganization> getOrganizations()
throws EamDbException {
2154 Connection conn = connect();
2156 List<EamOrganization> orgs =
new ArrayList<>();
2157 PreparedStatement preparedStatement = null;
2158 ResultSet resultSet = null;
2159 String sql =
"SELECT * FROM organizations";
2162 preparedStatement = conn.prepareStatement(sql);
2163 resultSet = preparedStatement.executeQuery();
2164 while (resultSet.next()) {
2165 orgs.add(getEamOrganizationFromResultSet(resultSet));
2169 }
catch (SQLException ex) {
2170 throw new EamDbException(
"Error getting all organizations.", ex);
2188 public EamOrganization getOrganizationByID(
int orgID)
throws EamDbException {
2189 Connection conn = connect();
2191 PreparedStatement preparedStatement = null;
2192 ResultSet resultSet = null;
2193 String sql =
"SELECT * FROM organizations WHERE id=?";
2196 preparedStatement = conn.prepareStatement(sql);
2197 preparedStatement.setInt(1, orgID);
2198 resultSet = preparedStatement.executeQuery();
2200 return getEamOrganizationFromResultSet(resultSet);
2202 }
catch (SQLException ex) {
2203 throw new EamDbException(
"Error getting organization by id.", ex);
2221 public EamOrganization getReferenceSetOrganization(
int referenceSetID)
throws EamDbException {
2223 EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
2224 if (globalSet == null) {
2225 throw new EamDbException(
"Reference set with ID " + referenceSetID +
" not found");
2227 return (getOrganizationByID(globalSet.
getOrgID()));
2239 throw new EamDbException(
"EamOrganization is null");
2241 throw new EamDbException(
"Organization has -1 row ID");
2254 public void updateOrganization(
EamOrganization updatedOrganization)
throws EamDbException {
2255 testArgument(updatedOrganization);
2257 Connection conn = connect();
2258 PreparedStatement preparedStatement = null;
2259 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2261 preparedStatement = conn.prepareStatement(sql);
2262 preparedStatement.setString(1, updatedOrganization.
getName());
2263 preparedStatement.setString(2, updatedOrganization.
getPocName());
2264 preparedStatement.setString(3, updatedOrganization.
getPocEmail());
2265 preparedStatement.setString(4, updatedOrganization.
getPocPhone());
2266 preparedStatement.setInt(5, updatedOrganization.
getOrgID());
2267 preparedStatement.executeUpdate();
2268 }
catch (SQLException ex) {
2269 throw new EamDbException(
"Error updating organization.", ex);
2277 public void deleteOrganization(
EamOrganization organizationToDelete)
throws EamDbException {
2278 testArgument(organizationToDelete);
2280 Connection conn = connect();
2281 PreparedStatement checkIfUsedStatement = null;
2282 ResultSet resultSet = null;
2283 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2284 PreparedStatement deleteOrgStatement = null;
2285 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2287 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2288 checkIfUsedStatement.setInt(1, organizationToDelete.
getOrgID());
2289 checkIfUsedStatement.setInt(2, organizationToDelete.
getOrgID());
2290 resultSet = checkIfUsedStatement.executeQuery();
2292 if (resultSet.getLong(1) > 0) {
2293 throw new EamDbException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2295 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2296 deleteOrgStatement.setInt(1, organizationToDelete.
getOrgID());
2297 deleteOrgStatement.executeUpdate();
2298 }
catch (SQLException ex) {
2299 throw new EamDbException(
"Error executing query when attempting to delete organization by id.", ex);
2318 public int newReferenceSet(
EamGlobalSet eamGlobalSet)
throws EamDbException {
2319 if (eamGlobalSet == null) {
2320 throw new EamDbException(
"EamGlobalSet is null");
2324 throw new EamDbException(
"File known status on the EamGlobalSet is null");
2327 if (eamGlobalSet.
getType() == null) {
2328 throw new EamDbException(
"Type on the EamGlobalSet is null");
2331 Connection conn = connect();
2333 PreparedStatement preparedStatement1 = null;
2334 PreparedStatement preparedStatement2 = null;
2335 ResultSet resultSet = null;
2336 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2337 + getConflictClause();
2338 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2341 preparedStatement1 = conn.prepareStatement(sql1);
2342 preparedStatement1.setInt(1, eamGlobalSet.
getOrgID());
2343 preparedStatement1.setString(2, eamGlobalSet.
getSetName());
2344 preparedStatement1.setString(3, eamGlobalSet.
getVersion());
2346 preparedStatement1.setBoolean(5, eamGlobalSet.
isReadOnly());
2347 preparedStatement1.setInt(6, eamGlobalSet.
getType().getId());
2348 preparedStatement1.setString(7, eamGlobalSet.
getImportDate().toString());
2350 preparedStatement1.executeUpdate();
2352 preparedStatement2 = conn.prepareStatement(sql2);
2353 preparedStatement2.setInt(1, eamGlobalSet.
getOrgID());
2354 preparedStatement2.setString(2, eamGlobalSet.
getSetName());
2355 preparedStatement2.setString(3, eamGlobalSet.
getVersion());
2356 preparedStatement2.setString(4, eamGlobalSet.
getImportDate().toString());
2358 resultSet = preparedStatement2.executeQuery();
2360 return resultSet.getInt(
"id");
2362 }
catch (SQLException ex) {
2363 throw new EamDbException(
"Error inserting new global set.", ex);
2382 public EamGlobalSet getReferenceSetByID(
int referenceSetID)
throws EamDbException {
2383 Connection conn = connect();
2385 PreparedStatement preparedStatement1 = null;
2386 ResultSet resultSet = null;
2387 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2390 preparedStatement1 = conn.prepareStatement(sql1);
2391 preparedStatement1.setInt(1, referenceSetID);
2392 resultSet = preparedStatement1.executeQuery();
2393 if (resultSet.next()) {
2394 return getEamGlobalSetFromResultSet(resultSet);
2399 }
catch (SQLException ex) {
2400 throw new EamDbException(
"Error getting reference set by id.", ex);
2420 if (correlationType == null) {
2421 throw new EamDbException(
"Correlation type is null");
2424 List<EamGlobalSet> results =
new ArrayList<>();
2425 Connection conn = connect();
2427 PreparedStatement preparedStatement1 = null;
2428 ResultSet resultSet = null;
2429 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
2432 preparedStatement1 = conn.prepareStatement(sql1);
2433 resultSet = preparedStatement1.executeQuery();
2434 while (resultSet.next()) {
2435 results.add(getEamGlobalSetFromResultSet(resultSet));
2438 }
catch (SQLException ex) {
2439 throw new EamDbException(
"Error getting reference sets.", ex);
2460 throw new EamDbException(
"Known status of EamGlobalFileInstance is null");
2462 if (correlationType == null) {
2463 throw new EamDbException(
"Correlation type is null");
2466 Connection conn = connect();
2468 PreparedStatement preparedStatement = null;
2470 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2471 + getConflictClause();
2475 preparedStatement.setInt(1, eamGlobalFileInstance.
getGlobalSetID());
2476 preparedStatement.setString(2, eamGlobalFileInstance.
getMD5Hash());
2477 preparedStatement.setByte(3, eamGlobalFileInstance.
getKnownStatus().getFileKnownValue());
2478 preparedStatement.setString(4, eamGlobalFileInstance.
getComment());
2479 preparedStatement.executeUpdate();
2480 }
catch (SQLException ex) {
2481 throw new EamDbException(
"Error inserting new reference instance into reference_ table.", ex);
2501 public boolean referenceSetExists(String referenceSetName, String version)
throws EamDbException {
2502 Connection conn = connect();
2504 PreparedStatement preparedStatement1 = null;
2505 ResultSet resultSet = null;
2506 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
2509 preparedStatement1 = conn.prepareStatement(sql1);
2510 preparedStatement1.setString(1, referenceSetName);
2511 preparedStatement1.setString(2, version);
2512 resultSet = preparedStatement1.executeQuery();
2513 return (resultSet.next());
2515 }
catch (SQLException ex) {
2516 throw new EamDbException(
"Error testing whether reference set exists (name: " + referenceSetName
2517 +
" version: " + version, ex);
2531 public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances,
CorrelationAttributeInstance.
Type contentType)
throws EamDbException {
2532 if (contentType == null) {
2533 throw new EamDbException(
"Correlation type is null");
2535 if (globalInstances == null) {
2536 throw new EamDbException(
"Null set of EamGlobalFileInstance");
2539 Connection conn = connect();
2541 PreparedStatement bulkPs = null;
2543 conn.setAutoCommit(
false);
2546 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2547 + getConflictClause();
2552 if (globalInstance.getKnownStatus() == null) {
2553 throw new EamDbException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
2556 bulkPs.setInt(1, globalInstance.getGlobalSetID());
2557 bulkPs.setString(2, globalInstance.getMD5Hash());
2558 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
2559 bulkPs.setString(4, globalInstance.getComment());
2563 bulkPs.executeBatch();
2565 }
catch (SQLException | EamDbException ex) {
2568 }
catch (SQLException ex2) {
2571 throw new EamDbException(
"Error inserting bulk artifacts.", ex);
2592 Connection conn = connect();
2594 List<EamGlobalFileInstance> globalFileInstances =
new ArrayList<>();
2595 PreparedStatement preparedStatement1 = null;
2596 ResultSet resultSet = null;
2597 String sql1 =
"SELECT * FROM %s WHERE value=?";
2601 preparedStatement1.setString(1, normalizeValued);
2602 resultSet = preparedStatement1.executeQuery();
2603 while (resultSet.next()) {
2604 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
2607 }
catch (SQLException ex) {
2608 throw new EamDbException(
"Error getting reference instances by type and value.", ex);
2615 return globalFileInstances;
2629 if (newType == null) {
2630 throw new EamDbException(
"Correlation type is null");
2633 if (-1 == newType.getId()) {
2634 typeId = newCorrelationTypeNotKnownId(newType);
2636 typeId = newCorrelationTypeKnownId(newType);
2653 Connection conn = connect();
2655 PreparedStatement preparedStatement = null;
2656 PreparedStatement preparedStatementQuery = null;
2657 ResultSet resultSet = null;
2662 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
2664 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2667 preparedStatement = conn.prepareStatement(insertSql);
2669 preparedStatement.setString(1, newType.getDisplayName());
2670 preparedStatement.setString(2, newType.getDbTableName());
2671 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
2672 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
2674 preparedStatement.executeUpdate();
2676 preparedStatementQuery = conn.prepareStatement(querySql);
2677 preparedStatementQuery.setString(1, newType.getDisplayName());
2678 preparedStatementQuery.setString(2, newType.getDbTableName());
2680 resultSet = preparedStatementQuery.executeQuery();
2681 if (resultSet.next()) {
2683 typeId = correlationType.getId();
2685 }
catch (SQLException ex) {
2686 throw new EamDbException(
"Error inserting new correlation type.", ex);
2706 Connection conn = connect();
2708 PreparedStatement preparedStatement = null;
2709 PreparedStatement preparedStatementQuery = null;
2710 ResultSet resultSet = null;
2715 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
2717 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
2720 preparedStatement = conn.prepareStatement(insertSql);
2722 preparedStatement.setInt(1, newType.getId());
2723 preparedStatement.setString(2, newType.getDisplayName());
2724 preparedStatement.setString(3, newType.getDbTableName());
2725 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
2726 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
2728 preparedStatement.executeUpdate();
2730 preparedStatementQuery = conn.prepareStatement(querySql);
2731 preparedStatementQuery.setString(1, newType.getDisplayName());
2732 preparedStatementQuery.setString(2, newType.getDbTableName());
2734 resultSet = preparedStatementQuery.executeQuery();
2735 if (resultSet.next()) {
2737 typeId = correlationType.getId();
2739 }
catch (SQLException ex) {
2740 throw new EamDbException(
"Error inserting new correlation type.", ex);
2752 Connection conn = connect();
2755 PreparedStatement preparedStatement = null;
2756 ResultSet resultSet = null;
2757 String sql =
"SELECT * FROM correlation_types";
2760 preparedStatement = conn.prepareStatement(sql);
2761 resultSet = preparedStatement.executeQuery();
2762 while (resultSet.next()) {
2763 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2767 }
catch (SQLException ex) {
2768 throw new EamDbException(
"Error getting all correlation types.", ex);
2787 Connection conn = connect();
2790 PreparedStatement preparedStatement = null;
2791 ResultSet resultSet = null;
2792 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
2795 preparedStatement = conn.prepareStatement(sql);
2796 resultSet = preparedStatement.executeQuery();
2797 while (resultSet.next()) {
2798 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2802 }
catch (SQLException ex) {
2803 throw new EamDbException(
"Error getting enabled correlation types.", ex);
2822 Connection conn = connect();
2825 PreparedStatement preparedStatement = null;
2826 ResultSet resultSet = null;
2827 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
2830 preparedStatement = conn.prepareStatement(sql);
2831 resultSet = preparedStatement.executeQuery();
2832 while (resultSet.next()) {
2833 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
2837 }
catch (SQLException ex) {
2838 throw new EamDbException(
"Error getting supported correlation types.", ex);
2855 Connection conn = connect();
2857 PreparedStatement preparedStatement = null;
2858 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
2861 preparedStatement = conn.prepareStatement(sql);
2862 preparedStatement.setString(1, aType.getDisplayName());
2863 preparedStatement.setString(2, aType.getDbTableName());
2864 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
2865 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
2866 preparedStatement.setInt(5, aType.getId());
2867 preparedStatement.executeUpdate();
2868 typeCache.put(aType.getId(), aType);
2869 }
catch (SQLException ex) {
2870 throw new EamDbException(
"Error updating correlation type.", ex);
2890 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
2891 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
2894 }
catch (ExecutionException ex) {
2895 throw new EamDbException(
"Error getting correlation type", ex);
2909 Connection conn = connect();
2912 PreparedStatement preparedStatement = null;
2913 ResultSet resultSet = null;
2914 String sql =
"SELECT * FROM correlation_types WHERE id=?";
2917 preparedStatement = conn.prepareStatement(sql);
2918 preparedStatement.setInt(1, typeId);
2919 resultSet = preparedStatement.executeQuery();
2920 if (resultSet.next()) {
2921 aType = getCorrelationTypeFromResultSet(resultSet);
2924 throw new EamDbException(
"Failed to find entry for correlation type ID = " + typeId);
2927 }
catch (SQLException ex) {
2928 throw new EamDbException(
"Error getting correlation type by id.", ex);
2946 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
2947 if (null == resultSet) {
2953 resultSet.getInt(
"org_id");
2954 if (!resultSet.wasNull()) {
2957 resultSet.getString(
"org_name"),
2958 resultSet.getString(
"poc_name"),
2959 resultSet.getString(
"poc_email"),
2960 resultSet.getString(
"poc_phone"));
2970 eamCase.
setNotes(resultSet.getString(
"notes"));
2975 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
2976 if (null == resultSet) {
2981 resultSet.getInt(
"case_id"),
2982 resultSet.getInt(
"id"),
2983 resultSet.getString(
"device_id"),
2984 resultSet.getString(
"name")
2987 return eamDataSource;
2991 if (null == resultSet) {
2996 resultSet.getInt(
"id"),
2997 resultSet.getString(
"display_name"),
2998 resultSet.getString(
"db_table_name"),
2999 resultSet.getBoolean(
"supported"),
3000 resultSet.getBoolean(
"enabled")
3003 return eamArtifactType;
3017 if (null == resultSet) {
3023 resultSet.getString(
"value"),
3024 resultSet.getInt(
"id"),
3025 new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), resultSet.getString(
"case_name")),
3026 new CorrelationDataSource(resultSet.getInt(
"case_id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name")),
3027 resultSet.getString(
"file_path"),
3028 resultSet.getString(
"comment"),
3029 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status"))
3033 private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3034 if (null == resultSet) {
3039 resultSet.getInt(
"id"),
3040 resultSet.getString(
"org_name"),
3041 resultSet.getString(
"poc_name"),
3042 resultSet.getString(
"poc_email"),
3043 resultSet.getString(
"poc_phone")
3047 private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, EamDbException {
3048 if (null == resultSet) {
3053 resultSet.getInt(
"id"),
3054 resultSet.getInt(
"org_id"),
3055 resultSet.getString(
"set_name"),
3056 resultSet.getString(
"version"),
3057 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3058 resultSet.getBoolean(
"read_only"),
3060 LocalDate.parse(resultSet.getString(
"import_date"))
3065 if (null == resultSet) {
3070 resultSet.getInt(
"id"),
3071 resultSet.getInt(
"reference_set_id"),
3072 resultSet.getString(
"value"),
3073 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3074 resultSet.getString(
"comment")
3084 public void upgradeSchema()
throws EamDbException, SQLException {
3086 ResultSet resultSet = null;
3087 Statement statement = null;
3088 Connection conn = null;
3092 conn.setAutoCommit(
false);
3093 statement = conn.createStatement();
3095 int minorVersion = 0;
3096 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
3097 if (resultSet.next()) {
3098 String minorVersionStr = resultSet.getString(
"value");
3100 minorVersion = Integer.parseInt(minorVersionStr);
3101 }
catch (NumberFormatException ex) {
3102 throw new EamDbException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", ex);
3106 int majorVersion = 0;
3107 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='SCHEMA_VERSION'");
3108 if (resultSet.next()) {
3109 String majorVersionStr = resultSet.getString(
"value");
3111 majorVersion = Integer.parseInt(majorVersionStr);
3112 }
catch (NumberFormatException ex) {
3113 throw new EamDbException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", ex);
3117 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3118 if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) {
3119 logger.log(Level.INFO,
"Central Repository is up to date");
3124 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3125 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3126 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3127 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3132 EamDbUtil.insertDefaultOrganization(conn);
3135 if (!updateSchemaVersion(conn)) {
3136 throw new EamDbException(
"Error updating schema version");
3140 logger.log(Level.INFO,
"Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION);
3141 }
catch (SQLException | EamDbException ex) {
3146 }
catch (SQLException ex2) {
3147 logger.log(Level.SEVERE,
"Database rollback failed", ex2);
TskData.FileKnown getKnownStatus()
String getExaminerPhone()
CorrelationAttributeInstance.Type getType()
static String correlationTypeToInstanceTableName(CorrelationAttributeInstance.Type type)
void setCreationDate(String creationDate)
static void closeResultSet(ResultSet resultSet)
static void closeStatement(Statement statement)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
String getCorrelationValue()
void setExaminerPhone(String examinerPhone)
void setExaminerName(String examinerName)
void setCaseNumber(String caseNumber)
static TimingMetric getTimingMetric(String name)
TskData.FileKnown getKnownStatus()
void process(ResultSet resultSet)
Type getCorrelationType()
void setOrg(EamOrganization org)
static String normalize(CorrelationAttributeInstance.Type attributeType, String data)
static EamDb getInstance()
void setNotes(String notes)
static void closeConnection(Connection conn)
void setKnownStatus(TskData.FileKnown knownStatus)
CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId)
TskData.FileKnown getFileKnownStatus()
CorrelationDataSource getCorrelationDataSource()
String getExaminerEmail()
LocalDate getImportDate()
String getExaminerPhone()
static void submitTimingMetric(TimingMetric metric)
synchronized static Logger getLogger(String name)
CorrelationCase getCorrelationCase()
static String correlationTypeToReferenceTableName(CorrelationAttributeInstance.Type type)
static EamOrganization getDefault()
void setExaminerEmail(String examinerEmail)
static final int FILES_TYPE_ID
String getExaminerEmail()