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.Arrays;
38 import java.util.HashMap;
40 import java.util.Optional;
42 import java.util.concurrent.ExecutionException;
43 import java.util.concurrent.TimeUnit;
44 import java.util.logging.Level;
45 import org.apache.commons.lang3.tuple.Pair;
46 import org.openide.util.NbBundle.Messages;
54 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
56 import org.
sleuthkit.datamodel.InvalidAccountIDException;
65 abstract class RdbmsCentralRepo
implements CentralRepository {
67 private final static Logger logger = Logger.getLogger(RdbmsCentralRepo.class.getName());
68 static final String SCHEMA_MAJOR_VERSION_KEY =
"SCHEMA_VERSION";
69 static final String SCHEMA_MINOR_VERSION_KEY =
"SCHEMA_MINOR_VERSION";
70 static final String CREATION_SCHEMA_MAJOR_VERSION_KEY =
"CREATION_SCHEMA_MAJOR_VERSION";
71 static final String CREATION_SCHEMA_MINOR_VERSION_KEY =
"CREATION_SCHEMA_MINOR_VERSION";
72 static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION =
new CaseDbSchemaVersionNumber(1, 6);
74 protected final List<CorrelationAttributeInstance.Type> defaultCorrelationTypes;
76 private int bulkArtifactsCount;
77 protected int bulkArtifactsThreshold;
78 private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
79 private static final int CASE_CACHE_TIMEOUT = 5;
80 private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
81 private static final int ACCOUNTS_CACHE_TIMEOUT = 5;
82 private static final Cache<String, Optional<CentralRepoAccountType>> accountTypesCache = CacheBuilder.newBuilder().build();
83 private static final Cache<Pair<CentralRepoAccountType, String>, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder()
84 .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES).
87 private boolean isCRTypeCacheInitialized;
88 private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build();
89 private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
90 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
92 private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
93 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
95 private static final Cache<String, CorrelationDataSource> dataSourceCacheByDsObjectId = CacheBuilder.newBuilder()
96 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
98 private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
99 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
102 static final int MAX_VALUE_LENGTH = 256;
106 static final int DEFAULT_BULK_THRESHHOLD = 1000;
108 private static final int QUERY_STR_MAX_LEN = 1000;
115 protected RdbmsCentralRepo() throws CentralRepoException {
116 isCRTypeCacheInitialized =
false;
117 bulkArtifactsCount = 0;
118 bulkArtifacts =
new HashMap<>();
120 defaultCorrelationTypes = CorrelationAttributeInstance.getDefaultCorrelationTypes();
121 defaultCorrelationTypes.forEach((type) -> {
122 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(type),
new ArrayList<>());
129 protected abstract Connection connect(
boolean foreignKeys)
throws CentralRepoException;
134 protected abstract Connection connect() throws CentralRepoException;
139 protected abstract Connection getEphemeralConnection();
150 public
void newDbInfo(String name, String value) throws CentralRepoException {
151 Connection conn = connect();
153 PreparedStatement preparedStatement = null;
154 String sql =
"INSERT INTO db_info (name, value) VALUES (?, ?) "
155 + getConflictClause();
157 preparedStatement = conn.prepareStatement(sql);
158 preparedStatement.setString(1, name);
159 preparedStatement.setString(2, value);
160 preparedStatement.executeUpdate();
161 }
catch (SQLException ex) {
162 throw new CentralRepoException(
"Error adding new name/value pair to db_info.", ex);
164 CentralRepoDbUtil.closeStatement(preparedStatement);
165 CentralRepoDbUtil.closeConnection(conn);
171 public void addDataSourceObjectId(
int rowId,
long dataSourceObjectId)
throws CentralRepoException {
172 Connection conn = connect();
173 PreparedStatement preparedStatement = null;
174 String sql =
"UPDATE data_sources SET datasource_obj_id=? WHERE id=?";
176 preparedStatement = conn.prepareStatement(sql);
177 preparedStatement.setLong(1, dataSourceObjectId);
178 preparedStatement.setInt(2, rowId);
179 preparedStatement.executeUpdate();
180 }
catch (SQLException ex) {
181 throw new CentralRepoException(
"Error updating data source object id for data_sources row " + rowId, ex);
183 CentralRepoDbUtil.closeStatement(preparedStatement);
184 CentralRepoDbUtil.closeConnection(conn);
198 public String getDbInfo(String name)
throws CentralRepoException {
199 Connection conn = connect();
201 PreparedStatement preparedStatement = null;
202 ResultSet resultSet = null;
204 String sql =
"SELECT value FROM db_info WHERE name=?";
206 preparedStatement = conn.prepareStatement(sql);
207 preparedStatement.setString(1, name);
208 resultSet = preparedStatement.executeQuery();
209 if (resultSet.next()) {
210 value = resultSet.getString(
"value");
212 }
catch (SQLException ex) {
213 throw new CentralRepoException(
"Error getting value for name.", ex);
215 CentralRepoDbUtil.closeResultSet(resultSet);
216 CentralRepoDbUtil.closeStatement(preparedStatement);
217 CentralRepoDbUtil.closeConnection(conn);
226 public final void clearCaches() {
227 synchronized (typeCache) {
228 typeCache.invalidateAll();
229 isCRTypeCacheInitialized =
false;
231 caseCacheByUUID.invalidateAll();
232 caseCacheById.invalidateAll();
233 dataSourceCacheByDsObjectId.invalidateAll();
234 dataSourceCacheById.invalidateAll();
235 accountsCache.invalidateAll();
247 public void updateDbInfo(String name, String value)
throws CentralRepoException {
248 Connection conn = connect();
250 PreparedStatement preparedStatement = null;
251 String sql =
"UPDATE db_info SET value=? WHERE name=?";
253 preparedStatement = conn.prepareStatement(sql);
254 preparedStatement.setString(1, value);
255 preparedStatement.setString(2, name);
256 preparedStatement.executeUpdate();
257 }
catch (SQLException ex) {
258 throw new CentralRepoException(
"Error updating value for name.", ex);
260 CentralRepoDbUtil.closeStatement(preparedStatement);
261 CentralRepoDbUtil.closeConnection(conn);
275 public synchronized CorrelationCase newCase(CorrelationCase eamCase)
throws CentralRepoException {
277 if (eamCase.getCaseUUID() == null) {
278 throw new CentralRepoException(
"Case UUID is null");
282 CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID());
283 if (cRCase != null) {
287 Connection conn = connect();
288 PreparedStatement preparedStatement = null;
290 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
291 +
"examiner_name, examiner_email, examiner_phone, notes) "
292 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
293 + getConflictClause();
294 ResultSet resultSet = null;
296 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
298 preparedStatement.setString(1, eamCase.getCaseUUID());
299 if (null == eamCase.getOrg()) {
300 preparedStatement.setNull(2, Types.INTEGER);
302 preparedStatement.setInt(2, eamCase.getOrg().getOrgID());
304 preparedStatement.setString(3, eamCase.getDisplayName());
305 preparedStatement.setString(4, eamCase.getCreationDate());
306 if (
"".equals(eamCase.getCaseNumber())) {
307 preparedStatement.setNull(5, Types.INTEGER);
309 preparedStatement.setString(5, eamCase.getCaseNumber());
311 if (
"".equals(eamCase.getExaminerName())) {
312 preparedStatement.setNull(6, Types.INTEGER);
314 preparedStatement.setString(6, eamCase.getExaminerName());
316 if (
"".equals(eamCase.getExaminerEmail())) {
317 preparedStatement.setNull(7, Types.INTEGER);
319 preparedStatement.setString(7, eamCase.getExaminerEmail());
321 if (
"".equals(eamCase.getExaminerPhone())) {
322 preparedStatement.setNull(8, Types.INTEGER);
324 preparedStatement.setString(8, eamCase.getExaminerPhone());
326 if (
"".equals(eamCase.getNotes())) {
327 preparedStatement.setNull(9, Types.INTEGER);
329 preparedStatement.setString(9, eamCase.getNotes());
332 preparedStatement.executeUpdate();
334 resultSet = preparedStatement.getGeneratedKeys();
335 if (!resultSet.next()) {
336 throw new CentralRepoException(String.format(
"Failed to INSERT case %s in central repo", eamCase.getCaseUUID()));
338 int caseID = resultSet.getInt(1);
339 CorrelationCase correlationCase =
new CorrelationCase(caseID, eamCase.getCaseUUID(), eamCase.getOrg(),
340 eamCase.getDisplayName(), eamCase.getCreationDate(), eamCase.getCaseNumber(), eamCase.getExaminerName(),
341 eamCase.getExaminerEmail(), eamCase.getExaminerPhone(), eamCase.getNotes());
342 caseCacheByUUID.put(eamCase.getCaseUUID(), correlationCase);
343 caseCacheById.put(caseID, correlationCase);
344 }
catch (SQLException ex) {
345 throw new CentralRepoException(
"Error inserting new case.", ex);
347 CentralRepoDbUtil.closeResultSet(resultSet);
348 CentralRepoDbUtil.closeStatement(preparedStatement);
349 CentralRepoDbUtil.closeConnection(conn);
353 return getCaseByUUID(eamCase.getCaseUUID());
362 public CorrelationCase newCase(Case autopsyCase)
throws CentralRepoException {
363 if (autopsyCase == null) {
364 throw new CentralRepoException(
"Case is null");
367 CorrelationCase curCeCase =
new CorrelationCase(
369 autopsyCase.getName(),
370 CentralRepoOrganization.getDefault(),
371 autopsyCase.getDisplayName(),
372 autopsyCase.getCreatedDate(),
373 autopsyCase.getNumber(),
374 autopsyCase.getExaminer(),
375 autopsyCase.getExaminerEmail(),
376 autopsyCase.getExaminerPhone(),
377 autopsyCase.getCaseNotes());
378 return newCase(curCeCase);
382 public CorrelationCase getCase(Case autopsyCase)
throws CentralRepoException {
383 return getCaseByUUID(autopsyCase.getName());
392 public void updateCase(CorrelationCase eamCase)
throws CentralRepoException {
393 if (eamCase == null) {
394 throw new CentralRepoException(
"Correlation case is null");
397 Connection conn = connect();
399 PreparedStatement preparedStatement = null;
400 String sql =
"UPDATE cases "
401 +
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
402 +
"WHERE case_uid=?";
405 preparedStatement = conn.prepareStatement(sql);
407 if (null == eamCase.getOrg()) {
408 preparedStatement.setNull(1, Types.INTEGER);
410 preparedStatement.setInt(1, eamCase.getOrg().getOrgID());
412 preparedStatement.setString(2, eamCase.getDisplayName());
413 preparedStatement.setString(3, eamCase.getCreationDate());
415 if (
"".equals(eamCase.getCaseNumber())) {
416 preparedStatement.setNull(4, Types.INTEGER);
418 preparedStatement.setString(4, eamCase.getCaseNumber());
420 if (
"".equals(eamCase.getExaminerName())) {
421 preparedStatement.setNull(5, Types.INTEGER);
423 preparedStatement.setString(5, eamCase.getExaminerName());
425 if (
"".equals(eamCase.getExaminerEmail())) {
426 preparedStatement.setNull(6, Types.INTEGER);
428 preparedStatement.setString(6, eamCase.getExaminerEmail());
430 if (
"".equals(eamCase.getExaminerPhone())) {
431 preparedStatement.setNull(7, Types.INTEGER);
433 preparedStatement.setString(7, eamCase.getExaminerPhone());
435 if (
"".equals(eamCase.getNotes())) {
436 preparedStatement.setNull(8, Types.INTEGER);
438 preparedStatement.setString(8, eamCase.getNotes());
441 preparedStatement.setString(9, eamCase.getCaseUUID());
443 preparedStatement.executeUpdate();
445 caseCacheById.put(eamCase.getID(), eamCase);
446 caseCacheByUUID.put(eamCase.getCaseUUID(), eamCase);
447 }
catch (SQLException ex) {
448 throw new CentralRepoException(
"Error updating case.", ex);
450 CentralRepoDbUtil.closeStatement(preparedStatement);
451 CentralRepoDbUtil.closeConnection(conn);
463 public CorrelationCase getCaseByUUID(String caseUUID)
throws CentralRepoException {
465 return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
466 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
469 }
catch (ExecutionException ex) {
470 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
481 private CorrelationCase getCaseByUUIDFromCr(String caseUUID)
throws CentralRepoException {
482 Connection conn = connect();
484 CorrelationCase eamCaseResult = null;
485 PreparedStatement preparedStatement = null;
486 ResultSet resultSet = null;
488 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
489 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
491 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
492 +
"WHERE case_uid=?";
495 preparedStatement = conn.prepareStatement(sql);
496 preparedStatement.setString(1, caseUUID);
497 resultSet = preparedStatement.executeQuery();
498 if (resultSet.next()) {
499 eamCaseResult = getEamCaseFromResultSet(resultSet);
501 if (eamCaseResult != null) {
503 caseCacheById.put(eamCaseResult.getID(), eamCaseResult);
505 }
catch (SQLException ex) {
506 throw new CentralRepoException(
"Error getting case details.", ex);
508 CentralRepoDbUtil.closeResultSet(resultSet);
509 CentralRepoDbUtil.closeStatement(preparedStatement);
510 CentralRepoDbUtil.closeConnection(conn);
513 return eamCaseResult;
524 public CorrelationCase getCaseById(
int caseId)
throws CentralRepoException {
526 return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
527 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
530 }
catch (ExecutionException ex) {
531 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
542 private CorrelationCase getCaseByIdFromCr(
int caseId)
throws CentralRepoException {
543 Connection conn = connect();
545 CorrelationCase eamCaseResult = null;
546 PreparedStatement preparedStatement = null;
547 ResultSet resultSet = null;
549 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
550 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
552 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
553 +
"WHERE cases.id=?";
555 preparedStatement = conn.prepareStatement(sql);
556 preparedStatement.setInt(1, caseId);
557 resultSet = preparedStatement.executeQuery();
558 if (resultSet.next()) {
559 eamCaseResult = getEamCaseFromResultSet(resultSet);
561 if (eamCaseResult != null) {
563 caseCacheByUUID.put(eamCaseResult.getCaseUUID(), eamCaseResult);
565 }
catch (SQLException ex) {
566 throw new CentralRepoException(
"Error getting case details.", ex);
568 CentralRepoDbUtil.closeResultSet(resultSet);
569 CentralRepoDbUtil.closeStatement(preparedStatement);
570 CentralRepoDbUtil.closeConnection(conn);
573 return eamCaseResult;
582 public List<CorrelationCase> getCases() throws CentralRepoException {
583 Connection conn = connect();
585 List<CorrelationCase> cases =
new ArrayList<>();
586 CorrelationCase eamCaseResult;
587 PreparedStatement preparedStatement = null;
588 ResultSet resultSet = null;
590 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
591 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
593 +
"LEFT JOIN organizations ON cases.org_id=organizations.id";
596 preparedStatement = conn.prepareStatement(sql);
597 resultSet = preparedStatement.executeQuery();
598 while (resultSet.next()) {
599 eamCaseResult = getEamCaseFromResultSet(resultSet);
600 cases.add(eamCaseResult);
602 }
catch (SQLException ex) {
603 throw new CentralRepoException(
"Error getting all cases.", ex);
605 CentralRepoDbUtil.closeResultSet(resultSet);
606 CentralRepoDbUtil.closeStatement(preparedStatement);
607 CentralRepoDbUtil.closeConnection(conn);
623 private static String getDataSourceByDSObjectIdCacheKey(
int caseId, Long dataSourceObjectId) {
624 return "Case" + caseId +
"DsObjectId" + dataSourceObjectId;
636 private static String getDataSourceByIdCacheKey(
int caseId,
int dataSourceId) {
637 return "Case" + caseId +
"Id" + dataSourceId;
646 public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource)
throws CentralRepoException {
647 if (eamDataSource.getCaseID() == -1) {
648 throw new CentralRepoException(
"Case ID is -1");
650 if (eamDataSource.getDeviceID() == null) {
651 throw new CentralRepoException(
"Device ID is null");
653 if (eamDataSource.getName() == null) {
654 throw new CentralRepoException(
"Name is null");
656 if (eamDataSource.getID() != -1) {
658 return eamDataSource;
661 Connection conn = connect();
663 PreparedStatement preparedStatement = null;
665 String sql =
"INSERT INTO data_sources(device_id, case_id, name, datasource_obj_id, md5, sha1, sha256) VALUES (?, ?, ?, ?, ?, ?, ?) "
666 + getConflictClause();
667 ResultSet resultSet = null;
669 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
671 preparedStatement.setString(1, eamDataSource.getDeviceID());
672 preparedStatement.setInt(2, eamDataSource.getCaseID());
673 preparedStatement.setString(3, eamDataSource.getName());
674 preparedStatement.setLong(4, eamDataSource.getDataSourceObjectID());
675 preparedStatement.setString(5, eamDataSource.getMd5());
676 preparedStatement.setString(6, eamDataSource.getSha1());
677 preparedStatement.setString(7, eamDataSource.getSha256());
679 preparedStatement.executeUpdate();
680 resultSet = preparedStatement.getGeneratedKeys();
681 if (!resultSet.next()) {
690 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
691 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
692 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
693 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
694 throw new CentralRepoException(String.format(
"Unable to to INSERT or get data source %s in central repo:", eamDataSource.getName()), getException);
698 int dataSourceId = resultSet.getInt(1);
699 CorrelationDataSource dataSource =
new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getDataSourceObjectID(), eamDataSource.getMd5(), eamDataSource.getSha1(), eamDataSource.getSha256());
700 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(dataSource.getCaseID(), dataSource.getDataSourceObjectID()), dataSource);
701 dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource);
705 }
catch (SQLException insertException) {
715 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
716 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
717 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
718 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
719 throw new CentralRepoException(String.format(
"Unable to to INSERT or get data source %s in central repo, insert failed due to Exception: %s", eamDataSource.getName(), insertException.getMessage()), getException);
722 CentralRepoDbUtil.closeResultSet(resultSet);
723 CentralRepoDbUtil.closeStatement(preparedStatement);
724 CentralRepoDbUtil.closeConnection(conn);
740 public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long dataSourceObjectId)
throws CentralRepoException {
742 if (correlationCase == null) {
743 throw new CentralRepoException(
"Correlation case is null");
746 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), dataSourceObjectId), () -> getDataSourceFromCr(correlationCase.getID(), dataSourceObjectId));
747 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
750 }
catch (ExecutionException ex) {
751 throw new CentralRepoException(
"Error getting data source from central repository", ex);
767 private CorrelationDataSource getDataSourceFromCr(
int correlationCaseId, Long dataSourceObjectId)
throws CentralRepoException {
768 Connection conn = connect();
770 CorrelationDataSource eamDataSourceResult = null;
771 PreparedStatement preparedStatement = null;
772 ResultSet resultSet = null;
774 String sql =
"SELECT * FROM data_sources WHERE datasource_obj_id=? AND case_id=?";
777 preparedStatement = conn.prepareStatement(sql);
778 preparedStatement.setLong(1, dataSourceObjectId);
779 preparedStatement.setInt(2, correlationCaseId);
780 resultSet = preparedStatement.executeQuery();
781 if (resultSet.next()) {
782 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
784 if (eamDataSourceResult != null) {
785 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCaseId, eamDataSourceResult.getID()), eamDataSourceResult);
787 }
catch (SQLException ex) {
788 throw new CentralRepoException(
"Error getting data source.", ex);
790 CentralRepoDbUtil.closeResultSet(resultSet);
791 CentralRepoDbUtil.closeStatement(preparedStatement);
792 CentralRepoDbUtil.closeConnection(conn);
795 return eamDataSourceResult;
808 public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
809 if (correlationCase == null) {
810 throw new CentralRepoException(
"Correlation case is null");
813 return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
814 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
817 }
catch (ExecutionException ex) {
818 throw new CentralRepoException(
"Error getting data source from central repository", ex);
831 private CorrelationDataSource getDataSourceByIdFromCr(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
832 Connection conn = connect();
834 CorrelationDataSource eamDataSourceResult = null;
835 PreparedStatement preparedStatement = null;
836 ResultSet resultSet = null;
838 String sql =
"SELECT * FROM data_sources WHERE id=? AND case_id=?";
841 preparedStatement = conn.prepareStatement(sql);
842 preparedStatement.setInt(1, dataSourceId);
843 preparedStatement.setInt(2, correlationCase.getID());
844 resultSet = preparedStatement.executeQuery();
845 if (resultSet.next()) {
846 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
848 if (eamDataSourceResult != null) {
849 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDataSourceObjectID()), eamDataSourceResult);
851 }
catch (SQLException ex) {
852 throw new CentralRepoException(
"Error getting data source.", ex);
854 CentralRepoDbUtil.closeResultSet(resultSet);
855 CentralRepoDbUtil.closeStatement(preparedStatement);
856 CentralRepoDbUtil.closeConnection(conn);
859 return eamDataSourceResult;
868 public List<CorrelationDataSource> getDataSources() throws CentralRepoException {
869 Connection conn = connect();
871 List<CorrelationDataSource> dataSources =
new ArrayList<>();
872 CorrelationDataSource eamDataSourceResult;
873 PreparedStatement preparedStatement = null;
874 ResultSet resultSet = null;
876 String sql =
"SELECT * FROM data_sources";
879 preparedStatement = conn.prepareStatement(sql);
880 resultSet = preparedStatement.executeQuery();
881 while (resultSet.next()) {
882 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
883 dataSources.add(eamDataSourceResult);
885 }
catch (SQLException ex) {
886 throw new CentralRepoException(
"Error getting all data sources.", ex);
888 CentralRepoDbUtil.closeResultSet(resultSet);
889 CentralRepoDbUtil.closeStatement(preparedStatement);
890 CentralRepoDbUtil.closeConnection(conn);
902 public void updateDataSourceMd5Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
903 updateDataSourceStringValue(eamDataSource,
"md5", eamDataSource.getMd5());
912 public void updateDataSourceSha1Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
913 updateDataSourceStringValue(eamDataSource,
"sha1", eamDataSource.getSha1());
923 public void updateDataSourceSha256Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
924 updateDataSourceStringValue(eamDataSource,
"sha256", eamDataSource.getSha256());
934 private void updateDataSourceStringValue(CorrelationDataSource eamDataSource, String column, String value)
throws CentralRepoException {
935 if (eamDataSource == null) {
936 throw new CentralRepoException(
"Correlation data source is null");
939 Connection conn = connect();
941 PreparedStatement preparedStatement = null;
942 String sql =
"UPDATE data_sources "
943 +
"SET " + column +
"=? "
947 preparedStatement = conn.prepareStatement(sql);
949 preparedStatement.setString(1, value);
950 preparedStatement.setInt(2, eamDataSource.getID());
952 preparedStatement.executeUpdate();
954 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()), eamDataSource);
955 dataSourceCacheById.put(getDataSourceByIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getID()), eamDataSource);
956 }
catch (SQLException ex) {
957 throw new CentralRepoException(String.format(
"Error updating data source (obj_id=%d).", eamDataSource.getDataSourceObjectID()), ex);
959 CentralRepoDbUtil.closeStatement(preparedStatement);
960 CentralRepoDbUtil.closeConnection(conn);
973 public void updateDataSourceName(CorrelationDataSource eamDataSource, String newName)
throws CentralRepoException {
975 Connection conn = connect();
977 PreparedStatement preparedStatement = null;
979 String sql =
"UPDATE data_sources SET name = ? WHERE id = ?";
982 preparedStatement = conn.prepareStatement(sql);
983 preparedStatement.setString(1, newName);
984 preparedStatement.setInt(2, eamDataSource.getID());
985 preparedStatement.executeUpdate();
987 CorrelationDataSource updatedDataSource =
new CorrelationDataSource(
988 eamDataSource.getCaseID(),
989 eamDataSource.getID(),
990 eamDataSource.getDeviceID(),
992 eamDataSource.getDataSourceObjectID(),
993 eamDataSource.getMd5(),
994 eamDataSource.getSha1(),
995 eamDataSource.getSha256());
997 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getDataSourceObjectID()), updatedDataSource);
998 dataSourceCacheById.put(getDataSourceByIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getID()), updatedDataSource);
999 }
catch (SQLException ex) {
1000 throw new CentralRepoException(
"Error updating name of data source with ID " + eamDataSource.getDataSourceObjectID()
1001 +
" to " + newName, ex);
1003 CentralRepoDbUtil.closeStatement(preparedStatement);
1004 CentralRepoDbUtil.closeConnection(conn);
1015 public void addArtifactInstance(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1016 checkAddArtifactInstanceNulls(eamArtifact);
1019 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1020 boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType());
1024 if (artifactHasAnAccount) {
1025 sql =
"INSERT INTO "
1027 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) "
1028 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
1029 + getConflictClause();
1031 sql =
"INSERT INTO "
1033 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1034 +
"VALUES (?, ?, ?, ?, ?, ?, ?) "
1035 + getConflictClause();
1038 try (Connection conn = connect();
1039 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1041 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1042 preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID());
1043 preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID());
1044 preparedStatement.setString(3, eamArtifact.getCorrelationValue());
1045 preparedStatement.setString(4, eamArtifact.getFilePath().toLowerCase());
1046 preparedStatement.setByte(5, eamArtifact.getKnownStatus().getFileKnownValue());
1048 if (
"".equals(eamArtifact.getComment())) {
1049 preparedStatement.setNull(6, Types.INTEGER);
1051 preparedStatement.setString(6, eamArtifact.getComment());
1053 preparedStatement.setLong(7, eamArtifact.getFileObjectId());
1056 if (artifactHasAnAccount) {
1057 if (eamArtifact.getAccountId() >= 0) {
1058 preparedStatement.setLong(8, eamArtifact.getAccountId());
1060 preparedStatement.setNull(8, Types.INTEGER);
1064 preparedStatement.executeUpdate();
1067 }
catch (SQLException ex) {
1068 throw new CentralRepoException(
"Error inserting new artifact into artifacts table.", ex);
1085 public CentralRepoAccount
getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws InvalidAccountIDException, CentralRepoException {
1087 String normalizedAccountID = CentralRepoAccount.normalizeAccountIdentifier(crAccountType, accountUniqueID);
1091 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
1093 insertSQL =
"INSERT INTO accounts (account_type_id, account_unique_identifier) VALUES (?, ?) " + getConflictClause();
1096 insertSQL =
"INSERT OR IGNORE INTO accounts (account_type_id, account_unique_identifier) VALUES (?, ?) ";
1099 throw new CentralRepoException(String.format(
"Cannot add account to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
1102 try (Connection connection = connect();
1103 PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);) {
1105 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1106 preparedStatement.setString(2, normalizedAccountID);
1108 preparedStatement.executeUpdate();
1111 return getAccount(crAccountType, normalizedAccountID);
1112 }
catch (SQLException ex) {
1113 throw new CentralRepoException(
"Error adding an account to CR database.", ex);
1118 public Optional<CentralRepoAccountType> getAccountTypeByName(String accountTypeName)
throws CentralRepoException {
1120 return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName));
1121 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
1122 throw new CentralRepoException(
"Error looking up CR account type in cache.", ex);
1127 public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException {
1129 Collection<CentralRepoAccountType> accountTypes =
new ArrayList<>();
1131 String sql =
"SELECT * FROM account_types";
1132 try (Connection conn = connect();
1133 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1135 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1136 while (resultSet.next()) {
1137 Account.Type acctType =
new Account.Type(resultSet.getString(
"type_name"), resultSet.getString(
"display_name"));
1138 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1140 accountTypes.add(crAccountType);
1143 }
catch (SQLException ex) {
1144 throw new CentralRepoException(
"Error getting account types from central repository.", ex);
1146 return accountTypes;
1158 private Optional<CentralRepoAccountType> getCRAccountTypeFromDb(String accountTypeName)
throws CentralRepoException {
1160 String sql =
"SELECT * FROM account_types WHERE type_name = ?";
1161 try (Connection conn = connect();
1162 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1164 preparedStatement.setString(1, accountTypeName);
1165 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1166 if (resultSet.next()) {
1167 Account.Type acctType =
new Account.Type(accountTypeName, resultSet.getString(
"display_name"));
1168 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1169 accountTypesCache.put(accountTypeName, Optional.of(crAccountType));
1170 return Optional.of(crAccountType);
1172 accountTypesCache.put(accountTypeName, Optional.empty());
1173 return Optional.empty();
1176 }
catch (SQLException ex) {
1177 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
1200 public CentralRepoAccount
getAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws InvalidAccountIDException, CentralRepoException {
1201 String normalizedAccountID = CentralRepoAccount.normalizeAccountIdentifier(crAccountType, accountUniqueID);
1202 CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, normalizedAccountID));
1203 if (crAccount == null) {
1204 crAccount = getCRAccountFromDb(crAccountType, normalizedAccountID);
1205 if (crAccount != null) {
1206 accountsCache.put(Pair.of(crAccountType, normalizedAccountID), crAccount);
1225 private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1227 CentralRepoAccount account = null;
1229 String sql =
"SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
1230 try (Connection connection = connect();
1231 PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
1233 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1234 preparedStatement.setString(2, accountUniqueID);
1236 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1237 if (resultSet.next()) {
1238 account =
new CentralRepoAccount(resultSet.getInt(
"id"), crAccountType, resultSet.getString(
"account_unique_identifier"));
1241 }
catch (SQLException ex) {
1242 throw new CentralRepoException(
"Error getting account type id", ex);
1248 private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1249 if (eamArtifact == null) {
1250 throw new CentralRepoException(
"CorrelationAttribute is null");
1252 if (eamArtifact.getCorrelationType() == null) {
1253 throw new CentralRepoException(
"Correlation type is null");
1255 if (eamArtifact.getCorrelationValue() == null) {
1256 throw new CentralRepoException(
"Correlation value is null");
1258 if (eamArtifact.getCorrelationValue().length() >= MAX_VALUE_LENGTH) {
1259 throw new CentralRepoException(
"Artifact value too long for central repository."
1260 +
"\nCorrelationArtifact ID: " + eamArtifact.getID()
1261 +
"\nCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1262 +
"\nCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1265 if (eamArtifact.getCorrelationCase() == null) {
1266 throw new CentralRepoException(
"CorrelationAttributeInstance case is null");
1268 if (eamArtifact.getCorrelationDataSource() == null) {
1269 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null");
1271 if (eamArtifact.getKnownStatus() == null) {
1272 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null");
1277 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1278 if (value == null) {
1279 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null value");
1281 return getArtifactInstancesByTypeValues(aType, Arrays.asList(value));
1285 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValues(CorrelationAttributeInstance.Type aType, List<String> values)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1286 if (aType == null) {
1287 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1289 if (values == null || values.isEmpty()) {
1290 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1292 return getArtifactInstances(prepareGetInstancesSql(aType, values), aType);
1296 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValuesAndCases(CorrelationAttributeInstance.Type aType, List<String> values, List<Integer> caseIds)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1297 if (aType == null) {
1298 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1300 if (values == null || values.isEmpty()) {
1301 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1303 if (caseIds == null || caseIds.isEmpty()) {
1304 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified cases");
1306 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1311 StringBuilder inValuesBuilder =
new StringBuilder(prepareGetInstancesSql(aType, values));
1312 inValuesBuilder.append(sql);
1313 inValuesBuilder.append(caseIds.stream().map(String::valueOf).collect(Collectors.joining(
"', '")));
1314 inValuesBuilder.append(
"')");
1315 return getArtifactInstances(inValuesBuilder.toString(), aType);
1330 private String prepareGetInstancesSql(CorrelationAttributeInstance.Type aType, List<String> values)
throws CorrelationAttributeNormalizationException {
1331 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1335 +
".id as instance_id,"
1340 +
" cases.*, organizations.org_name, organizations.poc_name, organizations.poc_email, organizations.poc_phone, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.datasource_obj_id, data_sources.md5, data_sources.sha1, data_sources.sha256 FROM "
1342 +
" LEFT JOIN cases ON "
1344 +
".case_id=cases.id"
1345 +
" LEFT JOIN organizations ON cases.org_id=organizations.id"
1346 +
" LEFT JOIN data_sources ON "
1348 +
".data_source_id=data_sources.id"
1349 +
" WHERE value IN (";
1350 StringBuilder inValuesBuilder =
new StringBuilder(sql);
1351 for (String value : values) {
1352 if (value != null) {
1353 inValuesBuilder.append(
"'");
1354 inValuesBuilder.append(CorrelationAttributeNormalizer.normalize(aType, value));
1355 inValuesBuilder.append(
"',");
1358 inValuesBuilder.deleteCharAt(inValuesBuilder.length() - 1);
1359 inValuesBuilder.append(
")");
1360 return inValuesBuilder.toString();
1377 private List<CorrelationAttributeInstance> getArtifactInstances(String sql, CorrelationAttributeInstance.Type aType) throws CorrelationAttributeNormalizationException, CentralRepoException {
1378 Connection conn = connect();
1379 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1380 CorrelationAttributeInstance artifactInstance;
1381 PreparedStatement preparedStatement = null;
1382 ResultSet resultSet = null;
1384 preparedStatement = conn.prepareStatement(sql);
1385 resultSet = preparedStatement.executeQuery();
1386 while (resultSet.next()) {
1387 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1388 artifactInstances.add(artifactInstance);
1390 }
catch (SQLException ex) {
1391 throw new CentralRepoException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
1393 CentralRepoDbUtil.closeResultSet(resultSet);
1394 CentralRepoDbUtil.closeStatement(preparedStatement);
1395 CentralRepoDbUtil.closeConnection(conn);
1397 return artifactInstances;
1411 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1412 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1414 Connection conn = connect();
1416 Long instanceCount = 0L;
1417 PreparedStatement preparedStatement = null;
1418 ResultSet resultSet = null;
1420 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1422 =
"SELECT count(*) FROM "
1427 preparedStatement = conn.prepareStatement(sql);
1428 preparedStatement.setString(1, normalizedValue);
1429 resultSet = preparedStatement.executeQuery();
1431 instanceCount = resultSet.getLong(1);
1432 }
catch (SQLException ex) {
1433 throw new CentralRepoException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1435 CentralRepoDbUtil.closeResultSet(resultSet);
1436 CentralRepoDbUtil.closeStatement(preparedStatement);
1437 CentralRepoDbUtil.closeConnection(conn);
1440 return instanceCount;
1444 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1445 if (corAttr == null) {
1446 throw new CentralRepoException(
"CorrelationAttribute is null");
1448 Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
1449 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1450 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1451 return commonalityPercentage.intValue();
1465 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1466 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1468 Connection conn = connect();
1470 Long instanceCount = 0L;
1471 PreparedStatement preparedStatement = null;
1472 ResultSet resultSet = null;
1474 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1476 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1478 +
" WHERE value=?) AS "
1480 +
"_distinct_case_data_source_tuple";
1483 preparedStatement = conn.prepareStatement(sql);
1484 preparedStatement.setString(1, normalizedValue);
1485 resultSet = preparedStatement.executeQuery();
1487 instanceCount = resultSet.getLong(1);
1488 }
catch (SQLException ex) {
1489 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1491 CentralRepoDbUtil.closeResultSet(resultSet);
1492 CentralRepoDbUtil.closeStatement(preparedStatement);
1493 CentralRepoDbUtil.closeConnection(conn);
1496 return instanceCount;
1500 public Long getCountCasesWithOtherInstances(CorrelationAttributeInstance instance)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1501 Long instanceCount = 0L;
1502 if (instance != null) {
1503 Long sourceObjID = instance.getFileObjectId();
1505 int correlationCaseId = instance.getCorrelationCase().getID();
1506 String normalizedValue = CorrelationAttributeNormalizer.normalize(instance.getCorrelationType(), instance.getCorrelationValue());
1507 Connection conn = connect();
1508 PreparedStatement preparedStatement = null;
1509 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(instance.getCorrelationType());
1510 ResultSet resultSet = null;
1512 if (correlationCaseId > 0 && sourceObjID != null) {
1515 =
"SELECT count(*) FROM (SELECT DISTINCT case_id FROM "
1517 +
" WHERE value=? AND NOT (file_obj_id=? AND case_id=?)) AS "
1519 +
"_other_case_count";
1520 preparedStatement = conn.prepareStatement(sql);
1521 preparedStatement.setString(1, normalizedValue);
1522 preparedStatement.setLong(2, sourceObjID);
1523 preparedStatement.setInt(3, correlationCaseId);
1527 =
"SELECT count(*) FROM (SELECT DISTINCT case_id FROM "
1529 +
" WHERE value=? AS "
1531 +
"_other_case_count";
1532 preparedStatement = conn.prepareStatement(sql);
1533 preparedStatement.setString(1, normalizedValue);
1535 resultSet = preparedStatement.executeQuery();
1537 instanceCount = resultSet.getLong(1);
1538 }
catch (SQLException ex) {
1539 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1541 CentralRepoDbUtil.closeResultSet(resultSet);
1542 CentralRepoDbUtil.closeStatement(preparedStatement);
1543 CentralRepoDbUtil.closeConnection(conn);
1547 return instanceCount;
1551 public Long getCountUniqueDataSources() throws CentralRepoException {
1552 Connection conn = connect();
1554 Long instanceCount = 0L;
1555 PreparedStatement preparedStatement = null;
1556 ResultSet resultSet = null;
1558 String stmt =
"SELECT count(*) FROM data_sources";
1561 preparedStatement = conn.prepareStatement(stmt);
1562 resultSet = preparedStatement.executeQuery();
1564 instanceCount = resultSet.getLong(1);
1565 }
catch (SQLException ex) {
1566 throw new CentralRepoException(
"Error counting data sources.", ex);
1568 CentralRepoDbUtil.closeResultSet(resultSet);
1569 CentralRepoDbUtil.closeStatement(preparedStatement);
1570 CentralRepoDbUtil.closeConnection(conn);
1573 return instanceCount;
1588 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws CentralRepoException {
1589 Connection conn = connect();
1591 Long instanceCount = 0L;
1592 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1593 PreparedStatement preparedStatement = null;
1594 ResultSet resultSet = null;
1597 String sql =
"SELECT 0 ";
1599 for (CorrelationAttributeInstance.Type type : artifactTypes) {
1600 String table_name = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1602 +=
"+ (SELECT count(*) FROM "
1604 +
" WHERE data_source_id=" + correlationDataSource.getID() +
")";
1607 preparedStatement = conn.prepareStatement(sql);
1609 resultSet = preparedStatement.executeQuery();
1611 instanceCount = resultSet.getLong(1);
1612 }
catch (SQLException ex) {
1613 throw new CentralRepoException(
"Error counting artifact instances by caseName/dataSource.", ex);
1615 CentralRepoDbUtil.closeResultSet(resultSet);
1616 CentralRepoDbUtil.closeStatement(preparedStatement);
1617 CentralRepoDbUtil.closeConnection(conn);
1620 return instanceCount;
1631 public void addAttributeInstanceBulk(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1633 if (eamArtifact.getCorrelationType() == null) {
1634 throw new CentralRepoException(
"Correlation type is null");
1637 synchronized (bulkArtifacts) {
1638 if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
1639 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()),
new ArrayList<>());
1641 bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
1642 bulkArtifactsCount++;
1644 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1645 commitAttributeInstancesBulk();
1655 protected abstract String getConflictClause();
1662 public void commitAttributeInstancesBulk() throws CentralRepoException {
1663 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1665 Connection conn = connect();
1666 PreparedStatement bulkPs = null;
1669 synchronized (bulkArtifacts) {
1670 if (bulkArtifactsCount == 0) {
1674 for (String tableName : bulkArtifacts.keySet()) {
1679 +
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1680 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1681 +
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) "
1682 + getConflictClause();
1684 bulkPs = conn.prepareStatement(sql);
1686 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
1687 for (CorrelationAttributeInstance eamArtifact : eamArtifacts) {
1689 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1691 if (eamArtifact.getCorrelationCase() == null) {
1692 throw new CentralRepoException(
"CorrelationAttributeInstance case is null for: "
1693 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1694 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1695 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1697 if (eamArtifact.getCorrelationDataSource() == null) {
1698 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null for: "
1699 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1700 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1701 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1703 if (eamArtifact.getKnownStatus() == null) {
1704 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null for: "
1705 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1706 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1707 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue()
1708 +
"\n\tEam Instance: "
1709 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1710 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID());
1713 if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) {
1714 bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
1715 bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID());
1716 bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
1717 bulkPs.setString(4, eamArtifact.getCorrelationValue());
1718 bulkPs.setString(5, eamArtifact.getFilePath());
1719 bulkPs.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
1720 if (
"".equals(eamArtifact.getComment())) {
1721 bulkPs.setNull(7, Types.INTEGER);
1723 bulkPs.setString(7, eamArtifact.getComment());
1725 bulkPs.setLong(8, eamArtifact.getFileObjectId());
1728 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1729 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1730 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1731 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue())
1732 +
"\n\tEam Instance: "
1733 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1734 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID()
1735 +
"\n\t\tFilePath: " + eamArtifact.getFilePath());
1741 bulkPs.executeBatch();
1742 bulkArtifacts.get(tableName).clear();
1745 TimingMetric timingMetric = HealthMonitor.getTimingMetric(
"Central Repository: Bulk insert");
1746 HealthMonitor.submitTimingMetric(timingMetric);
1749 bulkArtifactsCount = 0;
1751 }
catch (SQLException ex) {
1752 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
1754 CentralRepoDbUtil.closeStatement(bulkPs);
1755 CentralRepoDbUtil.closeConnection(conn);
1763 public void bulkInsertCases(List<CorrelationCase> cases)
throws CentralRepoException {
1764 if (cases == null) {
1765 throw new CentralRepoException(
"cases argument is null");
1768 if (cases.isEmpty()) {
1772 Connection conn = connect();
1775 PreparedStatement bulkPs = null;
1777 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1778 +
"examiner_name, examiner_email, examiner_phone, notes) "
1779 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1780 + getConflictClause();
1781 bulkPs = conn.prepareStatement(sql);
1783 for (CorrelationCase eamCase : cases) {
1784 bulkPs.setString(1, eamCase.getCaseUUID());
1785 if (null == eamCase.getOrg()) {
1786 bulkPs.setNull(2, Types.INTEGER);
1788 bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1790 bulkPs.setString(3, eamCase.getDisplayName());
1791 bulkPs.setString(4, eamCase.getCreationDate());
1793 if (
"".equals(eamCase.getCaseNumber())) {
1794 bulkPs.setNull(5, Types.INTEGER);
1796 bulkPs.setString(5, eamCase.getCaseNumber());
1798 if (
"".equals(eamCase.getExaminerName())) {
1799 bulkPs.setNull(6, Types.INTEGER);
1801 bulkPs.setString(6, eamCase.getExaminerName());
1803 if (
"".equals(eamCase.getExaminerEmail())) {
1804 bulkPs.setNull(7, Types.INTEGER);
1806 bulkPs.setString(7, eamCase.getExaminerEmail());
1808 if (
"".equals(eamCase.getExaminerPhone())) {
1809 bulkPs.setNull(8, Types.INTEGER);
1811 bulkPs.setString(8, eamCase.getExaminerPhone());
1813 if (
"".equals(eamCase.getNotes())) {
1814 bulkPs.setNull(9, Types.INTEGER);
1816 bulkPs.setString(9, eamCase.getNotes());
1824 if (counter >= bulkArtifactsThreshold) {
1825 bulkPs.executeBatch();
1830 bulkPs.executeBatch();
1831 }
catch (SQLException ex) {
1832 throw new CentralRepoException(
"Error inserting bulk cases.", ex);
1834 CentralRepoDbUtil.closeStatement(bulkPs);
1835 CentralRepoDbUtil.closeConnection(conn);
1849 public void updateAttributeInstanceComment(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1851 if (eamArtifact == null) {
1852 throw new CentralRepoException(
"CorrelationAttributeInstance is null");
1854 if (eamArtifact.getCorrelationCase() == null) {
1855 throw new CentralRepoException(
"Correlation case is null");
1857 if (eamArtifact.getCorrelationDataSource() == null) {
1858 throw new CentralRepoException(
"Correlation data source is null");
1860 Connection conn = connect();
1861 PreparedStatement preparedQuery = null;
1862 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1867 +
"WHERE case_id=? "
1868 +
"AND data_source_id=? "
1870 +
"AND file_path=?";
1873 preparedQuery = conn.prepareStatement(sqlUpdate);
1874 preparedQuery.setString(1, eamArtifact.getComment());
1875 preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID());
1876 preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID());
1877 preparedQuery.setString(4, eamArtifact.getCorrelationValue());
1878 preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
1879 preparedQuery.executeUpdate();
1880 }
catch (SQLException ex) {
1881 throw new CentralRepoException(
"Error getting/setting artifact instance comment=" + eamArtifact.getComment(), ex);
1883 CentralRepoDbUtil.closeStatement(preparedQuery);
1884 CentralRepoDbUtil.closeConnection(conn);
1903 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1904 CorrelationDataSource correlationDataSource,
long objectID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1906 if (correlationCase == null) {
1907 throw new CentralRepoException(
"Correlation case is null");
1910 Connection conn = connect();
1912 PreparedStatement preparedStatement = null;
1913 ResultSet resultSet = null;
1914 CorrelationAttributeInstance correlationAttributeInstance = null;
1918 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1920 =
"SELECT id, value, file_path, known_status, comment FROM "
1922 +
" WHERE case_id=?"
1923 +
" AND file_obj_id=?";
1925 preparedStatement = conn.prepareStatement(sql);
1926 preparedStatement.setInt(1, correlationCase.getID());
1927 preparedStatement.setInt(2, (
int) objectID);
1928 resultSet = preparedStatement.executeQuery();
1929 if (resultSet.next()) {
1930 int instanceId = resultSet.getInt(1);
1931 String value = resultSet.getString(2);
1932 String filePath = resultSet.getString(3);
1933 int knownStatus = resultSet.getInt(4);
1934 String comment = resultSet.getString(5);
1936 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1937 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
1939 }
catch (SQLException ex) {
1940 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1942 CentralRepoDbUtil.closeResultSet(resultSet);
1943 CentralRepoDbUtil.closeStatement(preparedStatement);
1944 CentralRepoDbUtil.closeConnection(conn);
1947 return correlationAttributeInstance;
1965 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1966 CorrelationDataSource correlationDataSource, String value, String filePath)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1968 if (correlationCase == null) {
1969 throw new CentralRepoException(
"Correlation case is null");
1971 if (correlationDataSource == null) {
1972 throw new CentralRepoException(
"Correlation data source is null");
1974 if (filePath == null) {
1975 throw new CentralRepoException(
"Correlation file path is null");
1978 Connection conn = connect();
1980 PreparedStatement preparedStatement = null;
1981 ResultSet resultSet = null;
1982 CorrelationAttributeInstance correlationAttributeInstance = null;
1985 String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
1987 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1989 =
"SELECT id, known_status, comment FROM "
1991 +
" WHERE case_id=?"
1992 +
" AND data_source_id=?"
1994 +
" AND file_path=?";
1996 preparedStatement = conn.prepareStatement(sql);
1997 preparedStatement.setInt(1, correlationCase.getID());
1998 preparedStatement.setInt(2, correlationDataSource.getID());
1999 preparedStatement.setString(3, normalizedValue);
2000 preparedStatement.setString(4, filePath.toLowerCase());
2001 resultSet = preparedStatement.executeQuery();
2002 if (resultSet.next()) {
2003 int instanceId = resultSet.getInt(1);
2004 int knownStatus = resultSet.getInt(2);
2005 String comment = resultSet.getString(3);
2007 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
2008 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
2010 }
catch (SQLException ex) {
2011 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2013 CentralRepoDbUtil.closeResultSet(resultSet);
2014 CentralRepoDbUtil.closeStatement(preparedStatement);
2015 CentralRepoDbUtil.closeConnection(conn);
2018 return correlationAttributeInstance;
2032 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws CentralRepoException {
2033 if (eamArtifact == null) {
2034 throw new CentralRepoException(
"CorrelationAttribute is null");
2036 if (knownStatus == null) {
2037 throw new CentralRepoException(
"Known status is null");
2040 if (eamArtifact.getCorrelationCase() == null) {
2041 throw new CentralRepoException(
"Correlation case is null");
2043 if (eamArtifact.getCorrelationDataSource() == null) {
2044 throw new CentralRepoException(
"Correlation data source is null");
2047 Connection conn = connect();
2049 PreparedStatement preparedUpdate = null;
2050 PreparedStatement preparedQuery = null;
2051 ResultSet resultSet = null;
2053 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
2058 +
" WHERE case_id=? "
2059 +
"AND data_source_id=? "
2061 +
"AND file_path=?";
2066 +
" SET known_status=? WHERE id=?";
2069 preparedQuery = conn.prepareStatement(sqlQuery);
2070 preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID());
2071 preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID());
2072 preparedQuery.setString(3, eamArtifact.getCorrelationValue());
2073 preparedQuery.setString(4, eamArtifact.getFilePath());
2074 resultSet = preparedQuery.executeQuery();
2075 if (resultSet.next()) {
2076 int instance_id = resultSet.getInt(
"id");
2077 preparedUpdate = conn.prepareStatement(sqlUpdate);
2079 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
2080 preparedUpdate.setInt(2, instance_id);
2082 preparedUpdate.executeUpdate();
2089 CorrelationCase correlationCaseWithId = getCaseByUUID(eamArtifact.getCorrelationCase().getCaseUUID());
2090 if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) {
2091 newDataSource(eamArtifact.getCorrelationDataSource());
2093 eamArtifact.setKnownStatus(knownStatus);
2094 addArtifactInstance(eamArtifact);
2097 }
catch (SQLException ex) {
2098 throw new CentralRepoException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
2100 CentralRepoDbUtil.closeResultSet(resultSet);
2101 CentralRepoDbUtil.closeStatement(preparedUpdate);
2102 CentralRepoDbUtil.closeStatement(preparedQuery);
2103 CentralRepoDbUtil.closeConnection(conn);
2116 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2118 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2120 Connection conn = connect();
2122 Long badInstances = 0L;
2123 PreparedStatement preparedStatement = null;
2124 ResultSet resultSet = null;
2126 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2128 =
"SELECT count(*) FROM "
2130 +
" WHERE value=? AND known_status=?";
2133 preparedStatement = conn.prepareStatement(sql);
2134 preparedStatement.setString(1, normalizedValue);
2135 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2136 resultSet = preparedStatement.executeQuery();
2138 badInstances = resultSet.getLong(1);
2139 }
catch (SQLException ex) {
2140 throw new CentralRepoException(
"Error getting count of notable artifact instances.", ex);
2142 CentralRepoDbUtil.closeResultSet(resultSet);
2143 CentralRepoDbUtil.closeStatement(preparedStatement);
2144 CentralRepoDbUtil.closeConnection(conn);
2147 return badInstances;
2163 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2165 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2167 Connection conn = connect();
2169 Collection<String> caseNames =
new LinkedHashSet<>();
2171 PreparedStatement preparedStatement = null;
2172 ResultSet resultSet = null;
2174 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2176 =
"SELECT DISTINCT case_name FROM "
2178 +
" INNER JOIN cases ON "
2180 +
".case_id=cases.id WHERE "
2184 +
".known_status=?";
2187 preparedStatement = conn.prepareStatement(sql);
2188 preparedStatement.setString(1, normalizedValue);
2189 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2190 resultSet = preparedStatement.executeQuery();
2191 while (resultSet.next()) {
2192 caseNames.add(resultSet.getString(
"case_name"));
2194 }
catch (SQLException ex) {
2195 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2197 CentralRepoDbUtil.closeResultSet(resultSet);
2198 CentralRepoDbUtil.closeStatement(preparedStatement);
2199 CentralRepoDbUtil.closeConnection(conn);
2202 return caseNames.stream().collect(Collectors.toList());
2218 public List<String> getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2220 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2222 Connection conn = connect();
2224 Collection<String> caseNames =
new LinkedHashSet<>();
2226 PreparedStatement preparedStatement = null;
2227 ResultSet resultSet = null;
2229 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2231 =
"SELECT DISTINCT case_name FROM "
2233 +
" INNER JOIN cases ON "
2235 +
".case_id=cases.id WHERE "
2240 preparedStatement = conn.prepareStatement(sql);
2241 preparedStatement.setString(1, normalizedValue);
2242 resultSet = preparedStatement.executeQuery();
2243 while (resultSet.next()) {
2244 caseNames.add(resultSet.getString(
"case_name"));
2246 }
catch (SQLException ex) {
2247 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2249 CentralRepoDbUtil.closeResultSet(resultSet);
2250 CentralRepoDbUtil.closeStatement(preparedStatement);
2251 CentralRepoDbUtil.closeConnection(conn);
2254 return caseNames.stream().collect(Collectors.toList());
2265 public void deleteReferenceSet(
int referenceSetID)
throws CentralRepoException {
2266 deleteReferenceSetEntries(referenceSetID);
2267 deleteReferenceSetEntry(referenceSetID);
2277 private void deleteReferenceSetEntry(
int referenceSetID)
throws CentralRepoException {
2278 Connection conn = connect();
2280 PreparedStatement preparedStatement = null;
2281 String sql =
"DELETE FROM reference_sets WHERE id=?";
2284 preparedStatement = conn.prepareStatement(sql);
2285 preparedStatement.setInt(1, referenceSetID);
2286 preparedStatement.executeUpdate();
2287 }
catch (SQLException ex) {
2288 throw new CentralRepoException(
"Error deleting reference set " + referenceSetID, ex);
2290 CentralRepoDbUtil.closeStatement(preparedStatement);
2291 CentralRepoDbUtil.closeConnection(conn);
2303 private void deleteReferenceSetEntries(
int referenceSetID)
throws CentralRepoException {
2304 Connection conn = connect();
2306 PreparedStatement preparedStatement = null;
2307 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2310 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
2313 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2314 preparedStatement.setInt(1, referenceSetID);
2315 preparedStatement.executeUpdate();
2316 }
catch (SQLException ex) {
2317 throw new CentralRepoException(
"Error deleting files from reference set " + referenceSetID, ex);
2319 CentralRepoDbUtil.closeStatement(preparedStatement);
2320 CentralRepoDbUtil.closeConnection(conn);
2338 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws CentralRepoException {
2339 CentralRepoFileSet refSet = this.getReferenceSetByID(referenceSetID);
2340 if (refSet == null) {
2344 return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
2359 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2360 return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
2364 public HashHitInfo lookupHash(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2365 int correlationTypeID = CorrelationAttributeInstance.FILES_TYPE_ID;
2366 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), hash);
2368 Connection conn = connect();
2370 PreparedStatement preparedStatement = null;
2371 ResultSet resultSet = null;
2372 String sql =
"SELECT value,comment FROM %s WHERE value=? AND reference_set_id=?";
2374 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2377 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2378 preparedStatement.setString(1, normalizeValued);
2379 preparedStatement.setInt(2, referenceSetID);
2380 resultSet = preparedStatement.executeQuery();
2381 if (resultSet.next()) {
2382 String comment = resultSet.getString(
"comment");
2383 String hashFound = resultSet.getString(
"value");
2384 HashHitInfo found =
new HashHitInfo(hashFound,
"",
"");
2385 found.addComment(comment);
2390 }
catch (SQLException ex) {
2391 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2393 CentralRepoDbUtil.closeResultSet(resultSet);
2394 CentralRepoDbUtil.closeStatement(preparedStatement);
2395 CentralRepoDbUtil.closeConnection(conn);
2409 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2411 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
2413 Connection conn = connect();
2415 Long matchingInstances = 0L;
2416 PreparedStatement preparedStatement = null;
2417 ResultSet resultSet = null;
2418 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2420 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2423 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2424 preparedStatement.setString(1, normalizeValued);
2425 preparedStatement.setInt(2, referenceSetID);
2426 resultSet = preparedStatement.executeQuery();
2428 matchingInstances = resultSet.getLong(1);
2429 }
catch (SQLException ex) {
2430 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2432 CentralRepoDbUtil.closeResultSet(resultSet);
2433 CentralRepoDbUtil.closeStatement(preparedStatement);
2434 CentralRepoDbUtil.closeConnection(conn);
2437 return 0 < matchingInstances;
2449 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2452 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
2455 if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
2459 Connection conn = connect();
2461 Long badInstances = 0L;
2462 PreparedStatement preparedStatement = null;
2463 ResultSet resultSet = null;
2464 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2467 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2468 preparedStatement.setString(1, normalizeValued);
2469 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2470 resultSet = preparedStatement.executeQuery();
2472 badInstances = resultSet.getLong(1);
2473 }
catch (SQLException ex) {
2474 throw new CentralRepoException(
"Error determining if artifact is notable by reference.", ex);
2476 CentralRepoDbUtil.closeResultSet(resultSet);
2477 CentralRepoDbUtil.closeStatement(preparedStatement);
2478 CentralRepoDbUtil.closeConnection(conn);
2481 return 0 < badInstances;
2493 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2495 throw new CentralRepoException(
"Correlation type is null");
2498 if (instanceTableCallback == null) {
2499 throw new CentralRepoException(
"Callback interface is null");
2502 Connection conn = connect();
2503 PreparedStatement preparedStatement = null;
2504 ResultSet resultSet = null;
2505 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2506 StringBuilder sql =
new StringBuilder();
2507 sql.append(
"select * from ");
2508 sql.append(tableName);
2511 preparedStatement = conn.prepareStatement(sql.toString());
2512 resultSet = preparedStatement.executeQuery();
2513 instanceTableCallback.process(resultSet);
2514 }
catch (SQLException ex) {
2515 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2517 CentralRepoDbUtil.closeResultSet(resultSet);
2518 CentralRepoDbUtil.closeStatement(preparedStatement);
2519 CentralRepoDbUtil.closeConnection(conn);
2533 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2535 throw new CentralRepoException(
"Correlation type is null");
2538 if (instanceTableCallback == null) {
2539 throw new CentralRepoException(
"Callback interface is null");
2542 if (whereClause == null) {
2543 throw new CentralRepoException(
"Where clause is null");
2546 Connection conn = connect();
2547 PreparedStatement preparedStatement = null;
2548 ResultSet resultSet = null;
2549 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2550 StringBuilder sql =
new StringBuilder(300);
2551 sql.append(
"select * from ")
2554 .append(whereClause);
2557 preparedStatement = conn.prepareStatement(sql.toString());
2558 resultSet = preparedStatement.executeQuery();
2559 instanceTableCallback.process(resultSet);
2560 }
catch (SQLException ex) {
2561 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2563 CentralRepoDbUtil.closeResultSet(resultSet);
2564 CentralRepoDbUtil.closeStatement(preparedStatement);
2565 CentralRepoDbUtil.closeConnection(conn);
2578 public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2580 if (instanceTableCallback == null) {
2581 throw new CentralRepoException(
"Callback interface is null");
2584 if (selectClause == null) {
2585 throw new CentralRepoException(
"Select clause is null");
2588 Connection conn = connect();
2589 PreparedStatement preparedStatement = null;
2590 ResultSet resultSet = null;
2591 StringBuilder sql =
new StringBuilder(300);
2592 sql.append(
"select ")
2593 .append(selectClause);
2596 preparedStatement = conn.prepareStatement(sql.toString());
2597 resultSet = preparedStatement.executeQuery();
2598 instanceTableCallback.process(resultSet);
2599 }
catch (SQLException ex) {
2600 throw new CentralRepoException(
"Error running query", ex);
2602 CentralRepoDbUtil.closeResultSet(resultSet);
2603 CentralRepoDbUtil.closeStatement(preparedStatement);
2604 CentralRepoDbUtil.closeConnection(conn);
2609 public void executeCommand(String sql, List<Object> params)
throws CentralRepoException {
2611 try (Connection conn = connect();) {
2613 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2616 if (params != null) {
2618 for (Object param : params) {
2619 preparedStatement.setObject(paramIndex, param);
2624 preparedStatement.executeUpdate();
2625 }
catch (SQLException ex) {
2626 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL %s", sql), ex);
2631 public void executeQuery(String sql, List<Object> params, CentralRepositoryDbQueryCallback queryCallback)
throws CentralRepoException {
2632 if (queryCallback == null) {
2633 throw new CentralRepoException(
"Query callback is null");
2636 try (Connection conn = connect();) {
2637 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2640 if (params != null) {
2642 for (Object param : params) {
2643 preparedStatement.setObject(paramIndex, param);
2648 try (ResultSet resultSet = preparedStatement.executeQuery();) {
2649 queryCallback.process(resultSet);
2651 }
catch (SQLException ex) {
2652 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL query %s", sql), ex);
2657 public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg)
throws CentralRepoException {
2658 if (eamOrg == null) {
2659 throw new CentralRepoException(
"EamOrganization is null");
2660 }
else if (eamOrg.getOrgID() != -1) {
2661 throw new CentralRepoException(
"EamOrganization already has an ID");
2664 Connection conn = connect();
2665 ResultSet generatedKeys = null;
2666 PreparedStatement preparedStatement = null;
2667 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2668 + getConflictClause();
2671 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2672 preparedStatement.setString(1, eamOrg.getName());
2673 preparedStatement.setString(2, eamOrg.getPocName());
2674 preparedStatement.setString(3, eamOrg.getPocEmail());
2675 preparedStatement.setString(4, eamOrg.getPocPhone());
2677 preparedStatement.executeUpdate();
2678 generatedKeys = preparedStatement.getGeneratedKeys();
2679 if (generatedKeys.next()) {
2680 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2683 throw new SQLException(
"Creating user failed, no ID obtained.");
2685 }
catch (SQLException ex) {
2686 throw new CentralRepoException(
"Error inserting new organization.", ex);
2688 CentralRepoDbUtil.closeResultSet(generatedKeys);
2689 CentralRepoDbUtil.closeStatement(preparedStatement);
2690 CentralRepoDbUtil.closeConnection(conn);
2702 public List<CentralRepoOrganization> getOrganizations() throws CentralRepoException {
2703 Connection conn = connect();
2705 List<CentralRepoOrganization> orgs =
new ArrayList<>();
2706 PreparedStatement preparedStatement = null;
2707 ResultSet resultSet = null;
2708 String sql =
"SELECT * FROM organizations";
2711 preparedStatement = conn.prepareStatement(sql);
2712 resultSet = preparedStatement.executeQuery();
2713 while (resultSet.next()) {
2714 orgs.add(getEamOrganizationFromResultSet(resultSet));
2718 }
catch (SQLException ex) {
2719 throw new CentralRepoException(
"Error getting all organizations.", ex);
2721 CentralRepoDbUtil.closeResultSet(resultSet);
2722 CentralRepoDbUtil.closeStatement(preparedStatement);
2723 CentralRepoDbUtil.closeConnection(conn);
2737 public CentralRepoOrganization getOrganizationByID(
int orgID)
throws CentralRepoException {
2738 Connection conn = connect();
2740 PreparedStatement preparedStatement = null;
2741 ResultSet resultSet = null;
2742 String sql =
"SELECT * FROM organizations WHERE id=?";
2745 preparedStatement = conn.prepareStatement(sql);
2746 preparedStatement.setInt(1, orgID);
2747 resultSet = preparedStatement.executeQuery();
2749 return getEamOrganizationFromResultSet(resultSet);
2751 }
catch (SQLException ex) {
2752 throw new CentralRepoException(
"Error getting organization by id.", ex);
2754 CentralRepoDbUtil.closeResultSet(resultSet);
2755 CentralRepoDbUtil.closeStatement(preparedStatement);
2756 CentralRepoDbUtil.closeConnection(conn);
2770 public CentralRepoOrganization getReferenceSetOrganization(
int referenceSetID)
throws CentralRepoException {
2772 CentralRepoFileSet globalSet = getReferenceSetByID(referenceSetID);
2773 if (globalSet == null) {
2774 throw new CentralRepoException(
"Reference set with ID " + referenceSetID +
" not found");
2776 return (getOrganizationByID(globalSet.getOrgID()));
2786 private void testArgument(CentralRepoOrganization
org)
throws CentralRepoException {
2788 throw new CentralRepoException(
"EamOrganization is null");
2789 }
else if (
org.getOrgID() == -1) {
2790 throw new CentralRepoException(
"Organization has -1 row ID");
2806 public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName)
throws CentralRepoException {
2808 String querySQL =
"SELECT * FROM examiners WHERE login_name = '" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"'";
2809 try (Connection connection = connect();
2810 Statement statement = connection.createStatement();
2811 ResultSet resultSet = statement.executeQuery(querySQL);) {
2813 if (resultSet.next()) {
2814 return new CentralRepoExaminer(resultSet.getLong(
"id"), resultSet.getString(
"login_name"));
2819 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
2821 insertSQL =
"INSERT INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')" + getConflictClause();
2824 insertSQL =
"INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')";
2827 throw new CentralRepoException(String.format(
"Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
2829 statement.execute(insertSQL);
2832 try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
2833 if (resultSet2.next()) {
2834 return new CentralRepoExaminer(resultSet2.getLong(
"id"), resultSet2.getString(
"login_name"));
2836 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName);
2840 }
catch (SQLException ex) {
2841 throw new CentralRepoException(
"Error inserting row in examiners", ex);
2845 }
catch (SQLException ex) {
2846 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName, ex);
2859 public void updateOrganization(CentralRepoOrganization updatedOrganization)
throws CentralRepoException {
2860 testArgument(updatedOrganization);
2862 Connection conn = connect();
2863 PreparedStatement preparedStatement = null;
2864 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2866 preparedStatement = conn.prepareStatement(sql);
2867 preparedStatement.setString(1, updatedOrganization.getName());
2868 preparedStatement.setString(2, updatedOrganization.getPocName());
2869 preparedStatement.setString(3, updatedOrganization.getPocEmail());
2870 preparedStatement.setString(4, updatedOrganization.getPocPhone());
2871 preparedStatement.setInt(5, updatedOrganization.getOrgID());
2872 preparedStatement.executeUpdate();
2873 }
catch (SQLException ex) {
2874 throw new CentralRepoException(
"Error updating organization.", ex);
2876 CentralRepoDbUtil.closeStatement(preparedStatement);
2877 CentralRepoDbUtil.closeConnection(conn);
2882 public void deleteOrganization(CentralRepoOrganization organizationToDelete)
throws CentralRepoException {
2883 testArgument(organizationToDelete);
2885 Connection conn = connect();
2886 PreparedStatement checkIfUsedStatement = null;
2887 ResultSet resultSet = null;
2888 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2889 PreparedStatement deleteOrgStatement = null;
2890 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2892 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2893 checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
2894 checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
2895 resultSet = checkIfUsedStatement.executeQuery();
2897 if (resultSet.getLong(1) > 0) {
2898 throw new CentralRepoException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2900 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2901 deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
2902 deleteOrgStatement.executeUpdate();
2903 }
catch (SQLException ex) {
2904 throw new CentralRepoException(
"Error executing query when attempting to delete organization by id.", ex);
2906 CentralRepoDbUtil.closeResultSet(resultSet);
2907 CentralRepoDbUtil.closeStatement(checkIfUsedStatement);
2908 CentralRepoDbUtil.closeStatement(deleteOrgStatement);
2909 CentralRepoDbUtil.closeConnection(conn);
2923 public int newReferenceSet(CentralRepoFileSet eamGlobalSet)
throws CentralRepoException {
2924 if (eamGlobalSet == null) {
2925 throw new CentralRepoException(
"EamGlobalSet is null");
2928 if (eamGlobalSet.getFileKnownStatus() == null) {
2929 throw new CentralRepoException(
"File known status on the EamGlobalSet is null");
2932 if (eamGlobalSet.getType() == null) {
2933 throw new CentralRepoException(
"Type on the EamGlobalSet is null");
2936 Connection conn = connect();
2938 PreparedStatement preparedStatement1 = null;
2939 PreparedStatement preparedStatement2 = null;
2940 ResultSet resultSet = null;
2941 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2942 + getConflictClause();
2943 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2946 preparedStatement1 = conn.prepareStatement(sql1);
2947 preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
2948 preparedStatement1.setString(2, eamGlobalSet.getSetName());
2949 preparedStatement1.setString(3, eamGlobalSet.getVersion());
2950 preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
2951 preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
2952 preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
2953 preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
2955 preparedStatement1.executeUpdate();
2957 preparedStatement2 = conn.prepareStatement(sql2);
2958 preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
2959 preparedStatement2.setString(2, eamGlobalSet.getSetName());
2960 preparedStatement2.setString(3, eamGlobalSet.getVersion());
2961 preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
2963 resultSet = preparedStatement2.executeQuery();
2965 return resultSet.getInt(
"id");
2967 }
catch (SQLException ex) {
2968 throw new CentralRepoException(
"Error inserting new global set.", ex);
2970 CentralRepoDbUtil.closeResultSet(resultSet);
2971 CentralRepoDbUtil.closeStatement(preparedStatement1);
2972 CentralRepoDbUtil.closeStatement(preparedStatement2);
2973 CentralRepoDbUtil.closeConnection(conn);
2987 public CentralRepoFileSet getReferenceSetByID(
int referenceSetID)
throws CentralRepoException {
2988 Connection conn = connect();
2990 PreparedStatement preparedStatement1 = null;
2991 ResultSet resultSet = null;
2992 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2995 preparedStatement1 = conn.prepareStatement(sql1);
2996 preparedStatement1.setInt(1, referenceSetID);
2997 resultSet = preparedStatement1.executeQuery();
2998 if (resultSet.next()) {
2999 return getEamGlobalSetFromResultSet(resultSet);
3004 }
catch (SQLException ex) {
3005 throw new CentralRepoException(
"Error getting reference set by id.", ex);
3007 CentralRepoDbUtil.closeResultSet(resultSet);
3008 CentralRepoDbUtil.closeStatement(preparedStatement1);
3009 CentralRepoDbUtil.closeConnection(conn);
3023 public List<CentralRepoFileSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3025 if (correlationType == null) {
3026 throw new CentralRepoException(
"Correlation type is null");
3029 List<CentralRepoFileSet> results =
new ArrayList<>();
3030 Connection conn = connect();
3032 PreparedStatement preparedStatement1 = null;
3033 ResultSet resultSet = null;
3034 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
3037 preparedStatement1 = conn.prepareStatement(sql1);
3038 resultSet = preparedStatement1.executeQuery();
3039 while (resultSet.next()) {
3040 results.add(getEamGlobalSetFromResultSet(resultSet));
3043 }
catch (SQLException ex) {
3044 throw new CentralRepoException(
"Error getting reference sets.", ex);
3046 CentralRepoDbUtil.closeResultSet(resultSet);
3047 CentralRepoDbUtil.closeStatement(preparedStatement1);
3048 CentralRepoDbUtil.closeConnection(conn);
3063 public void addReferenceInstance(CentralRepoFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3064 if (eamGlobalFileInstance.getKnownStatus() == null) {
3065 throw new CentralRepoException(
"Known status of EamGlobalFileInstance is null");
3067 if (correlationType == null) {
3068 throw new CentralRepoException(
"Correlation type is null");
3071 Connection conn = connect();
3073 PreparedStatement preparedStatement = null;
3075 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3076 + getConflictClause();
3079 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(correlationType)));
3080 preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
3081 preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
3082 preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
3083 preparedStatement.setString(4, eamGlobalFileInstance.getComment());
3084 preparedStatement.executeUpdate();
3085 }
catch (SQLException ex) {
3086 throw new CentralRepoException(
"Error inserting new reference instance into reference_ table.", ex);
3088 CentralRepoDbUtil.closeStatement(preparedStatement);
3089 CentralRepoDbUtil.closeConnection(conn);
3106 public boolean referenceSetExists(String referenceSetName, String version)
throws CentralRepoException {
3107 Connection conn = connect();
3109 PreparedStatement preparedStatement1 = null;
3110 ResultSet resultSet = null;
3111 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
3114 preparedStatement1 = conn.prepareStatement(sql1);
3115 preparedStatement1.setString(1, referenceSetName);
3116 preparedStatement1.setString(2, version);
3117 resultSet = preparedStatement1.executeQuery();
3118 return (resultSet.next());
3120 }
catch (SQLException ex) {
3121 throw new CentralRepoException(
"Error testing whether reference set exists (name: " + referenceSetName
3122 +
" version: " + version, ex);
3124 CentralRepoDbUtil.closeResultSet(resultSet);
3125 CentralRepoDbUtil.closeStatement(preparedStatement1);
3126 CentralRepoDbUtil.closeConnection(conn);
3136 public void bulkInsertReferenceTypeEntries(Set<CentralRepoFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws CentralRepoException {
3137 if (contentType == null) {
3138 throw new CentralRepoException(
"Correlation type is null");
3140 if (globalInstances == null) {
3141 throw new CentralRepoException(
"Null set of EamGlobalFileInstance");
3144 Connection conn = connect();
3146 PreparedStatement bulkPs = null;
3148 conn.setAutoCommit(
false);
3151 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3152 + getConflictClause();
3154 bulkPs = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(contentType)));
3156 for (CentralRepoFileInstance globalInstance : globalInstances) {
3157 if (globalInstance.getKnownStatus() == null) {
3158 throw new CentralRepoException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
3161 bulkPs.setInt(1, globalInstance.getGlobalSetID());
3162 bulkPs.setString(2, globalInstance.getMD5Hash());
3163 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
3164 bulkPs.setString(4, globalInstance.getComment());
3168 bulkPs.executeBatch();
3170 }
catch (SQLException | CentralRepoException ex) {
3173 }
catch (SQLException ex2) {
3176 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
3178 CentralRepoDbUtil.closeStatement(bulkPs);
3179 CentralRepoDbUtil.closeConnection(conn);
3194 public List<CentralRepoFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws CentralRepoException, CorrelationAttributeNormalizationException {
3195 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
3197 Connection conn = connect();
3199 List<CentralRepoFileInstance> globalFileInstances =
new ArrayList<>();
3200 PreparedStatement preparedStatement1 = null;
3201 ResultSet resultSet = null;
3202 String sql1 =
"SELECT * FROM %s WHERE value=?";
3205 preparedStatement1 = conn.prepareStatement(String.format(sql1, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
3206 preparedStatement1.setString(1, normalizeValued);
3207 resultSet = preparedStatement1.executeQuery();
3208 while (resultSet.next()) {
3209 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
3212 }
catch (SQLException ex) {
3213 throw new CentralRepoException(
"Error getting reference instances by type and value.", ex);
3215 CentralRepoDbUtil.closeResultSet(resultSet);
3216 CentralRepoDbUtil.closeStatement(preparedStatement1);
3217 CentralRepoDbUtil.closeConnection(conn);
3220 return globalFileInstances;
3233 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3234 if (newType == null) {
3235 throw new CentralRepoException(
"Correlation type is null");
3238 if (-1 == newType.getId()) {
3239 typeId = newCorrelationTypeNotKnownId(newType);
3241 typeId = newCorrelationTypeKnownId(newType);
3244 synchronized (typeCache) {
3245 typeCache.put(newType.getId(), newType);
3260 public int newCorrelationTypeNotKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3261 Connection conn = connect();
3263 PreparedStatement preparedStatement = null;
3264 PreparedStatement preparedStatementQuery = null;
3265 ResultSet resultSet = null;
3270 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
3272 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3275 preparedStatement = conn.prepareStatement(insertSql);
3277 preparedStatement.setString(1, newType.getDisplayName());
3278 preparedStatement.setString(2, newType.getDbTableName());
3279 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
3280 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
3282 preparedStatement.executeUpdate();
3284 preparedStatementQuery = conn.prepareStatement(querySql);
3285 preparedStatementQuery.setString(1, newType.getDisplayName());
3286 preparedStatementQuery.setString(2, newType.getDbTableName());
3288 resultSet = preparedStatementQuery.executeQuery();
3289 if (resultSet.next()) {
3290 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3291 typeId = correlationType.getId();
3293 }
catch (SQLException ex) {
3294 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3296 CentralRepoDbUtil.closeResultSet(resultSet);
3297 CentralRepoDbUtil.closeStatement(preparedStatement);
3298 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3299 CentralRepoDbUtil.closeConnection(conn);
3313 private int newCorrelationTypeKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3314 Connection conn = connect();
3316 PreparedStatement preparedStatement = null;
3317 PreparedStatement preparedStatementQuery = null;
3318 ResultSet resultSet = null;
3323 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3325 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3328 preparedStatement = conn.prepareStatement(insertSql);
3330 preparedStatement.setInt(1, newType.getId());
3331 preparedStatement.setString(2, newType.getDisplayName());
3332 preparedStatement.setString(3, newType.getDbTableName());
3333 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
3334 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
3336 preparedStatement.executeUpdate();
3338 preparedStatementQuery = conn.prepareStatement(querySql);
3339 preparedStatementQuery.setString(1, newType.getDisplayName());
3340 preparedStatementQuery.setString(2, newType.getDbTableName());
3342 resultSet = preparedStatementQuery.executeQuery();
3343 if (resultSet.next()) {
3344 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3345 typeId = correlationType.getId();
3347 }
catch (SQLException ex) {
3348 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3350 CentralRepoDbUtil.closeResultSet(resultSet);
3351 CentralRepoDbUtil.closeStatement(preparedStatement);
3352 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3353 CentralRepoDbUtil.closeConnection(conn);
3359 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws CentralRepoException {
3361 synchronized (typeCache) {
3362 if (isCRTypeCacheInitialized ==
false) {
3363 getCorrelationTypesFromCr();
3365 return new ArrayList<>(typeCache.asMap().values());
3379 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws CentralRepoException {
3380 Connection conn = connect();
3382 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3383 PreparedStatement preparedStatement = null;
3384 ResultSet resultSet = null;
3385 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3388 preparedStatement = conn.prepareStatement(sql);
3389 resultSet = preparedStatement.executeQuery();
3390 while (resultSet.next()) {
3391 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3395 }
catch (SQLException ex) {
3396 throw new CentralRepoException(
"Error getting enabled correlation types.", ex);
3398 CentralRepoDbUtil.closeResultSet(resultSet);
3399 CentralRepoDbUtil.closeStatement(preparedStatement);
3400 CentralRepoDbUtil.closeConnection(conn);
3414 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws CentralRepoException {
3415 Connection conn = connect();
3417 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3418 PreparedStatement preparedStatement = null;
3419 ResultSet resultSet = null;
3420 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3423 preparedStatement = conn.prepareStatement(sql);
3424 resultSet = preparedStatement.executeQuery();
3425 while (resultSet.next()) {
3426 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3430 }
catch (SQLException ex) {
3431 throw new CentralRepoException(
"Error getting supported correlation types.", ex);
3433 CentralRepoDbUtil.closeResultSet(resultSet);
3434 CentralRepoDbUtil.closeStatement(preparedStatement);
3435 CentralRepoDbUtil.closeConnection(conn);
3447 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws CentralRepoException {
3448 Connection conn = connect();
3450 PreparedStatement preparedStatement = null;
3451 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3454 preparedStatement = conn.prepareStatement(sql);
3455 preparedStatement.setString(1, aType.getDisplayName());
3456 preparedStatement.setString(2, aType.getDbTableName());
3457 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3458 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3459 preparedStatement.setInt(5, aType.getId());
3460 preparedStatement.executeUpdate();
3461 synchronized (typeCache) {
3462 typeCache.put(aType.getId(), aType);
3464 }
catch (SQLException ex) {
3465 throw new CentralRepoException(
"Error updating correlation type.", ex);
3467 CentralRepoDbUtil.closeStatement(preparedStatement);
3468 CentralRepoDbUtil.closeConnection(conn);
3483 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws CentralRepoException {
3485 synchronized (typeCache) {
3486 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3488 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3491 }
catch (ExecutionException ex) {
3492 throw new CentralRepoException(
"Error getting correlation type", ex);
3505 private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(
int typeId)
throws CentralRepoException {
3506 Connection conn = connect();
3508 CorrelationAttributeInstance.Type aType;
3509 PreparedStatement preparedStatement = null;
3510 ResultSet resultSet = null;
3511 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3514 preparedStatement = conn.prepareStatement(sql);
3515 preparedStatement.setInt(1, typeId);
3516 resultSet = preparedStatement.executeQuery();
3517 if (resultSet.next()) {
3518 aType = getCorrelationTypeFromResultSet(resultSet);
3521 throw new CentralRepoException(
"Failed to find entry for correlation type ID = " + typeId);
3524 }
catch (SQLException ex) {
3525 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
3527 CentralRepoDbUtil.closeResultSet(resultSet);
3528 CentralRepoDbUtil.closeStatement(preparedStatement);
3529 CentralRepoDbUtil.closeConnection(conn);
3539 private void getCorrelationTypesFromCr() throws CentralRepoException {
3542 synchronized (typeCache) {
3543 typeCache.invalidateAll();
3544 isCRTypeCacheInitialized =
false;
3547 String sql =
"SELECT * FROM correlation_types";
3548 try (Connection conn = connect();
3549 PreparedStatement preparedStatement = conn.prepareStatement(sql);
3550 ResultSet resultSet = preparedStatement.executeQuery();) {
3552 synchronized (typeCache) {
3553 while (resultSet.next()) {
3554 CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
3555 typeCache.put(aType.getId(), aType);
3557 isCRTypeCacheInitialized =
true;
3559 }
catch (SQLException ex) {
3560 throw new CentralRepoException(
"Error getting correlation types.", ex);
3574 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3575 if (null == resultSet) {
3579 CentralRepoOrganization eamOrg = null;
3581 resultSet.getInt(
"org_id");
3582 if (!resultSet.wasNull()) {
3584 eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3585 resultSet.getString(
"org_name"),
3586 resultSet.getString(
"poc_name"),
3587 resultSet.getString(
"poc_email"),
3588 resultSet.getString(
"poc_phone"));
3591 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3592 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3593 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3598 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3599 if (null == resultSet) {
3603 CorrelationDataSource eamDataSource =
new CorrelationDataSource(
3604 resultSet.getInt(
"case_id"),
3605 resultSet.getInt(
"id"),
3606 resultSet.getString(
"device_id"),
3607 resultSet.getString(
"name"),
3608 resultSet.getLong(
"datasource_obj_id"),
3609 resultSet.getString(
"md5"),
3610 resultSet.getString(
"sha1"),
3611 resultSet.getString(
"sha256")
3614 return eamDataSource;
3617 private CorrelationAttributeInstance.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
throws CentralRepoException, SQLException {
3618 if (null == resultSet) {
3622 CorrelationAttributeInstance.Type eamArtifactType =
new CorrelationAttributeInstance.Type(
3623 resultSet.getInt(
"id"),
3624 resultSet.getString(
"display_name"),
3625 resultSet.getString(
"db_table_name"),
3626 resultSet.getBoolean(
"supported"),
3627 resultSet.getBoolean(
"enabled")
3630 return eamArtifactType;
3643 private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3644 if (null == resultSet) {
3648 CentralRepoOrganization eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3649 resultSet.getString(
"org_name"),
3650 resultSet.getString(
"poc_name"),
3651 resultSet.getString(
"poc_email"),
3652 resultSet.getString(
"poc_phone"));
3654 return new CorrelationAttributeInstance(
3656 resultSet.getString(
"value"),
3657 resultSet.getInt(
"instance_id"),
3658 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3659 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3660 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3661 new CorrelationDataSource(
3662 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3663 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3664 resultSet.getString(
"file_path"),
3665 resultSet.getString(
"comment"),
3666 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3667 resultSet.getLong(
"file_obj_id"));
3670 private CentralRepoOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3671 if (null == resultSet) {
3675 return new CentralRepoOrganization(
3676 resultSet.getInt(
"id"),
3677 resultSet.getString(
"org_name"),
3678 resultSet.getString(
"poc_name"),
3679 resultSet.getString(
"poc_email"),
3680 resultSet.getString(
"poc_phone")
3684 private CentralRepoFileSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException {
3685 if (null == resultSet) {
3689 return new CentralRepoFileSet(
3690 resultSet.getInt(
"id"),
3691 resultSet.getInt(
"org_id"),
3692 resultSet.getString(
"set_name"),
3693 resultSet.getString(
"version"),
3694 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3695 resultSet.getBoolean(
"read_only"),
3696 CentralRepository.getInstance().getCorrelationTypeById(resultSet.getInt(
"type")),
3697 LocalDate.parse(resultSet.getString(
"import_date"))
3701 private CentralRepoFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3702 if (null == resultSet) {
3706 return new CentralRepoFileInstance(
3707 resultSet.getInt(
"id"),
3708 resultSet.getInt(
"reference_set_id"),
3709 resultSet.getString(
"value"),
3710 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3711 resultSet.getString(
"comment")
3715 private String getPlatformSpecificInsertSQL(String sql)
throws CentralRepoException {
3717 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
3719 return "INSERT " + sql +
" ON CONFLICT DO NOTHING";
3721 return "INSERT OR IGNORE " + sql;
3724 throw new CentralRepoException(
"Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform());
3738 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3745 @Messages({
"AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository.",
3746 "# {0} - minorVersion",
3747 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3748 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3749 "# {0} - majorVersion",
3750 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3751 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3752 "# {0} - platformName",
3753 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3755 public void upgradeSchema() throws CentralRepoException, SQLException, IncompatibleCentralRepoException {
3757 ResultSet resultSet = null;
3758 Statement statement = null;
3759 PreparedStatement preparedStatement = null;
3760 Connection conn = null;
3761 CentralRepoPlatforms selectedPlatform = null;
3764 conn = connect(
false);
3765 conn.setAutoCommit(
false);
3766 statement = conn.createStatement();
3767 selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
3768 int minorVersion = 0;
3769 String minorVersionStr = null;
3770 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"'");
3771 if (resultSet.next()) {
3772 minorVersionStr = resultSet.getString(
"value");
3774 minorVersion = Integer.parseInt(minorVersionStr);
3775 }
catch (NumberFormatException ex) {
3776 throw new CentralRepoException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3779 throw new CentralRepoException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3782 int majorVersion = 0;
3783 String majorVersionStr = null;
3784 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"'");
3785 if (resultSet.next()) {
3786 majorVersionStr = resultSet.getString(
"value");
3788 majorVersion = Integer.parseInt(majorVersionStr);
3789 }
catch (NumberFormatException ex) {
3790 throw new CentralRepoException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3793 throw new CentralRepoException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3804 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3809 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3810 throw new IncompatibleCentralRepoException(Bundle.AbstractSqlEamDb_upgradeSchema_incompatible());
3812 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3813 logger.log(Level.INFO,
"Central Repository is up to date");
3816 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3817 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3824 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3825 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3826 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3827 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3832 CentralRepoDbUtil.insertDefaultOrganization(conn);
3838 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3839 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3841 final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
3842 final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
3843 final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
3844 final String addValueIndexTemplate = RdbmsCentralRepoFactory.getAddValueIndexTemplate();
3845 final String addKnownStatusIndexTemplate = RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate();
3846 final String addObjectIdIndexTemplate = RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate();
3848 final String addAttributeSql;
3850 switch (selectedPlatform) {
3852 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3855 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3858 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3861 final String dataSourcesTableName =
"data_sources";
3862 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3863 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3864 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3866 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3867 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3868 List<String> instaceTablesToAdd =
new ArrayList<>();
3870 final String wirelessNetworksDbTableName =
"wireless_networks";
3871 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3872 final String macAddressDbTableName =
"mac_address";
3873 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3874 final String imeiNumberDbTableName =
"imei_number";
3875 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3876 final String iccidNumberDbTableName =
"iccid_number";
3877 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3878 final String imsiNumberDbTableName =
"imsi_number";
3879 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3882 preparedStatement = conn.prepareStatement(addAttributeSql);
3883 preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID);
3884 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3885 preparedStatement.setString(3, wirelessNetworksDbTableName);
3886 preparedStatement.setInt(4, 1);
3887 preparedStatement.setInt(5, 1);
3888 preparedStatement.execute();
3891 preparedStatement = conn.prepareStatement(addAttributeSql);
3892 preparedStatement.setInt(1, CorrelationAttributeInstance.MAC_TYPE_ID);
3893 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3894 preparedStatement.setString(3, macAddressDbTableName);
3895 preparedStatement.setInt(4, 1);
3896 preparedStatement.setInt(5, 1);
3897 preparedStatement.execute();
3900 preparedStatement = conn.prepareStatement(addAttributeSql);
3901 preparedStatement.setInt(1, CorrelationAttributeInstance.IMEI_TYPE_ID);
3902 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3903 preparedStatement.setString(3, imeiNumberDbTableName);
3904 preparedStatement.setInt(4, 1);
3905 preparedStatement.setInt(5, 1);
3906 preparedStatement.execute();
3909 preparedStatement = conn.prepareStatement(addAttributeSql);
3910 preparedStatement.setInt(1, CorrelationAttributeInstance.IMSI_TYPE_ID);
3911 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3912 preparedStatement.setString(3, imsiNumberDbTableName);
3913 preparedStatement.setInt(4, 1);
3914 preparedStatement.setInt(5, 1);
3915 preparedStatement.execute();
3918 preparedStatement = conn.prepareStatement(addAttributeSql);
3919 preparedStatement.setInt(1, CorrelationAttributeInstance.ICCID_TYPE_ID);
3920 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3921 preparedStatement.setString(3, iccidNumberDbTableName);
3922 preparedStatement.setInt(4, 1);
3923 preparedStatement.setInt(5, 1);
3924 preparedStatement.execute();
3927 for (String tableName : instaceTablesToAdd) {
3928 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3929 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3930 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3931 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3932 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3936 String instance_type_dbname;
3937 final String objectIdColumnName =
"file_obj_id";
3938 for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
3939 instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
3940 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3941 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3943 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3949 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3950 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3952 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3953 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3955 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3956 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3967 String creationMajorVer;
3968 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3969 if (resultSet.next()) {
3970 creationMajorVer = resultSet.getString(
"value");
3972 creationMajorVer =
"0";
3974 String creationMinorVer;
3975 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3976 if (resultSet.next()) {
3977 creationMinorVer = resultSet.getString(
"value");
3979 creationMinorVer =
"0";
3981 statement.execute(
"DROP TABLE db_info");
3982 if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) {
3983 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3985 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3987 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3988 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3989 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3990 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
3995 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
3996 switch (selectedPlatform) {
3998 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
4000 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
4004 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
4005 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
4006 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
4008 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
4009 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
4010 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
4011 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
4012 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
4013 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesNameIndexStatement());
4014 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesObjectIdIndexStatement());
4015 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
4016 statement.execute(
"DROP TABLE old_data_sources");
4019 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
4024 (
new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
4027 (
new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);
4030 (
new CentralRepoDbUpgrader15To16()).upgradeSchema(dbSchemaVersion, conn);
4032 updateSchemaVersion(conn);
4034 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
4035 }
catch (SQLException | CentralRepoException ex) {
4040 }
catch (SQLException ex2) {
4041 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
4045 CentralRepoDbUtil.closeResultSet(resultSet);
4046 CentralRepoDbUtil.closeStatement(preparedStatement);
4047 CentralRepoDbUtil.closeStatement(statement);
4048 CentralRepoDbUtil.closeConnection(conn);
CentralRepoAccount getAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)