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 CentralRepoException(
"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 CentralRepoException(
"Cannot get artifact instances for null type");
1289 if (values == null || values.isEmpty()) {
1290 throw new CentralRepoException(
"Cannot get artifact instances without specified values");
1292 return getCorrAttrInstances(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 CentralRepoException(
"Cannot get artifact instances for null type");
1300 if (values == null || values.isEmpty()) {
1301 throw new CentralRepoException(
"Cannot get artifact instances without specified values");
1303 if (caseIds == null || caseIds.isEmpty()) {
1304 throw new CentralRepoException(
"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 getCorrAttrInstances(inValuesBuilder.toString(), aType);
1330 private String prepareGetInstancesSql(CorrelationAttributeInstance.Type aType, List<String> values)
throws CorrelationAttributeNormalizationException, CentralRepoException {
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();
1382 private List<CorrelationAttributeInstance> getCorrAttrInstances(String sql, CorrelationAttributeInstance.Type attrType) throws CorrelationAttributeNormalizationException, CentralRepoException {
1383 List<CorrelationAttributeInstance> corrAttrs =
new ArrayList<>();
1384 Connection conn = connect();
1385 PreparedStatement preparedStatement = null;
1386 ResultSet resultSet = null;
1388 preparedStatement = conn.prepareStatement(sql);
1389 resultSet = preparedStatement.executeQuery();
1390 while (resultSet.next()) {
1391 CorrelationAttributeInstance corrAttr = getCorrAttrFromResultSet(resultSet, attrType);
1392 corrAttrs.add(corrAttr);
1394 }
catch (SQLException ex) {
1395 throw new CentralRepoException(String.format(
"Error getting correlation attributes using query %s", sql), ex);
1397 CentralRepoDbUtil.closeResultSet(resultSet);
1398 CentralRepoDbUtil.closeStatement(preparedStatement);
1399 CentralRepoDbUtil.closeConnection(conn);
1415 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1416 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1418 Connection conn = connect();
1420 Long instanceCount = 0L;
1421 PreparedStatement preparedStatement = null;
1422 ResultSet resultSet = null;
1424 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1426 =
"SELECT count(*) FROM "
1431 preparedStatement = conn.prepareStatement(sql);
1432 preparedStatement.setString(1, normalizedValue);
1433 resultSet = preparedStatement.executeQuery();
1435 instanceCount = resultSet.getLong(1);
1436 }
catch (SQLException ex) {
1437 throw new CentralRepoException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1439 CentralRepoDbUtil.closeResultSet(resultSet);
1440 CentralRepoDbUtil.closeStatement(preparedStatement);
1441 CentralRepoDbUtil.closeConnection(conn);
1444 return instanceCount;
1448 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1449 if (corAttr == null) {
1450 throw new CentralRepoException(
"CorrelationAttribute is null");
1452 Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
1453 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1454 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1455 return commonalityPercentage.intValue();
1469 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1470 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1472 Connection conn = connect();
1474 Long instanceCount = 0L;
1475 PreparedStatement preparedStatement = null;
1476 ResultSet resultSet = null;
1478 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1480 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1482 +
" WHERE value=?) AS "
1484 +
"_distinct_case_data_source_tuple";
1487 preparedStatement = conn.prepareStatement(sql);
1488 preparedStatement.setString(1, normalizedValue);
1489 resultSet = preparedStatement.executeQuery();
1491 instanceCount = resultSet.getLong(1);
1492 }
catch (SQLException ex) {
1493 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1495 CentralRepoDbUtil.closeResultSet(resultSet);
1496 CentralRepoDbUtil.closeStatement(preparedStatement);
1497 CentralRepoDbUtil.closeConnection(conn);
1500 return instanceCount;
1504 public Long getCountCasesWithOtherInstances(CorrelationAttributeInstance instance)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1505 Long instanceCount = 0L;
1506 if (instance != null) {
1507 Long sourceObjID = instance.getFileObjectId();
1509 int correlationCaseId = instance.getCorrelationCase().getID();
1510 int correlationDataSourceId = instance.getCorrelationDataSource().getID();
1511 String normalizedValue = CorrelationAttributeNormalizer.normalize(instance.getCorrelationType(), instance.getCorrelationValue());
1512 Connection conn = connect();
1513 PreparedStatement preparedStatement = null;
1514 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(instance.getCorrelationType());
1515 ResultSet resultSet = null;
1518 if (correlationCaseId > 0 && sourceObjID != null && correlationDataSourceId > 0) {
1521 =
"SELECT count(*) FROM (SELECT DISTINCT case_id FROM "
1523 +
" WHERE value=? AND NOT (file_obj_id=? AND case_id=? AND data_source_id=?)) AS "
1525 +
"_other_case_count";
1526 preparedStatement = conn.prepareStatement(sql);
1527 preparedStatement.setString(1, normalizedValue);
1528 preparedStatement.setLong(2, sourceObjID);
1529 preparedStatement.setInt(3, correlationCaseId);
1530 preparedStatement.setInt(4, correlationDataSourceId);
1534 =
"SELECT count(*) FROM (SELECT DISTINCT case_id FROM "
1536 +
" WHERE value=? AS "
1538 +
"_other_case_count";
1539 preparedStatement = conn.prepareStatement(sql);
1540 preparedStatement.setString(1, normalizedValue);
1542 resultSet = preparedStatement.executeQuery();
1544 instanceCount = resultSet.getLong(1);
1545 }
catch (SQLException ex) {
1546 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1548 CentralRepoDbUtil.closeResultSet(resultSet);
1549 CentralRepoDbUtil.closeStatement(preparedStatement);
1550 CentralRepoDbUtil.closeConnection(conn);
1554 return instanceCount;
1558 public Long getCountUniqueDataSources() throws CentralRepoException {
1559 Connection conn = connect();
1561 Long instanceCount = 0L;
1562 PreparedStatement preparedStatement = null;
1563 ResultSet resultSet = null;
1565 String stmt =
"SELECT count(*) FROM data_sources";
1568 preparedStatement = conn.prepareStatement(stmt);
1569 resultSet = preparedStatement.executeQuery();
1571 instanceCount = resultSet.getLong(1);
1572 }
catch (SQLException ex) {
1573 throw new CentralRepoException(
"Error counting data sources.", ex);
1575 CentralRepoDbUtil.closeResultSet(resultSet);
1576 CentralRepoDbUtil.closeStatement(preparedStatement);
1577 CentralRepoDbUtil.closeConnection(conn);
1580 return instanceCount;
1595 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws CentralRepoException {
1596 Connection conn = connect();
1598 Long instanceCount = 0L;
1599 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1600 PreparedStatement preparedStatement = null;
1601 ResultSet resultSet = null;
1604 String sql =
"SELECT 0 ";
1606 for (CorrelationAttributeInstance.Type type : artifactTypes) {
1607 String table_name = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1609 +=
"+ (SELECT count(*) FROM "
1611 +
" WHERE data_source_id=" + correlationDataSource.getID() +
")";
1614 preparedStatement = conn.prepareStatement(sql);
1616 resultSet = preparedStatement.executeQuery();
1618 instanceCount = resultSet.getLong(1);
1619 }
catch (SQLException ex) {
1620 throw new CentralRepoException(
"Error counting artifact instances by caseName/dataSource.", ex);
1622 CentralRepoDbUtil.closeResultSet(resultSet);
1623 CentralRepoDbUtil.closeStatement(preparedStatement);
1624 CentralRepoDbUtil.closeConnection(conn);
1627 return instanceCount;
1638 public void addAttributeInstanceBulk(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1640 if (eamArtifact.getCorrelationType() == null) {
1641 throw new CentralRepoException(
"Correlation type is null");
1644 synchronized (bulkArtifacts) {
1645 if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
1646 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()),
new ArrayList<>());
1648 bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
1649 bulkArtifactsCount++;
1651 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1652 commitAttributeInstancesBulk();
1662 protected abstract String getConflictClause();
1669 public void commitAttributeInstancesBulk() throws CentralRepoException {
1670 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1672 Connection conn = connect();
1673 PreparedStatement bulkPs = null;
1676 synchronized (bulkArtifacts) {
1677 if (bulkArtifactsCount == 0) {
1681 for (String tableName : bulkArtifacts.keySet()) {
1686 +
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1687 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1688 +
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) "
1689 + getConflictClause();
1691 bulkPs = conn.prepareStatement(sql);
1693 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
1694 for (CorrelationAttributeInstance eamArtifact : eamArtifacts) {
1696 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1698 if (eamArtifact.getCorrelationCase() == null) {
1699 throw new CentralRepoException(
"CorrelationAttributeInstance case is null for: "
1700 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1701 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1702 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1704 if (eamArtifact.getCorrelationDataSource() == null) {
1705 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null for: "
1706 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1707 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1708 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1710 if (eamArtifact.getKnownStatus() == null) {
1711 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null for: "
1712 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1713 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1714 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue()
1715 +
"\n\tEam Instance: "
1716 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1717 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID());
1720 if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) {
1721 bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
1722 bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID());
1723 bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
1724 bulkPs.setString(4, eamArtifact.getCorrelationValue());
1725 bulkPs.setString(5, eamArtifact.getFilePath());
1726 bulkPs.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
1727 if (
"".equals(eamArtifact.getComment())) {
1728 bulkPs.setNull(7, Types.INTEGER);
1730 bulkPs.setString(7, eamArtifact.getComment());
1732 bulkPs.setLong(8, eamArtifact.getFileObjectId());
1735 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1736 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1737 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1738 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue())
1739 +
"\n\tEam Instance: "
1740 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1741 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID()
1742 +
"\n\t\tFilePath: " + eamArtifact.getFilePath());
1748 bulkPs.executeBatch();
1749 bulkArtifacts.get(tableName).clear();
1752 TimingMetric timingMetric = HealthMonitor.getTimingMetric(
"Central Repository: Bulk insert");
1753 HealthMonitor.submitTimingMetric(timingMetric);
1756 bulkArtifactsCount = 0;
1758 }
catch (SQLException ex) {
1759 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
1761 CentralRepoDbUtil.closeStatement(bulkPs);
1762 CentralRepoDbUtil.closeConnection(conn);
1770 public void bulkInsertCases(List<CorrelationCase> cases)
throws CentralRepoException {
1771 if (cases == null) {
1772 throw new CentralRepoException(
"cases argument is null");
1775 if (cases.isEmpty()) {
1779 Connection conn = connect();
1782 PreparedStatement bulkPs = null;
1784 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1785 +
"examiner_name, examiner_email, examiner_phone, notes) "
1786 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1787 + getConflictClause();
1788 bulkPs = conn.prepareStatement(sql);
1790 for (CorrelationCase eamCase : cases) {
1791 bulkPs.setString(1, eamCase.getCaseUUID());
1792 if (null == eamCase.getOrg()) {
1793 bulkPs.setNull(2, Types.INTEGER);
1795 bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1797 bulkPs.setString(3, eamCase.getDisplayName());
1798 bulkPs.setString(4, eamCase.getCreationDate());
1800 if (
"".equals(eamCase.getCaseNumber())) {
1801 bulkPs.setNull(5, Types.INTEGER);
1803 bulkPs.setString(5, eamCase.getCaseNumber());
1805 if (
"".equals(eamCase.getExaminerName())) {
1806 bulkPs.setNull(6, Types.INTEGER);
1808 bulkPs.setString(6, eamCase.getExaminerName());
1810 if (
"".equals(eamCase.getExaminerEmail())) {
1811 bulkPs.setNull(7, Types.INTEGER);
1813 bulkPs.setString(7, eamCase.getExaminerEmail());
1815 if (
"".equals(eamCase.getExaminerPhone())) {
1816 bulkPs.setNull(8, Types.INTEGER);
1818 bulkPs.setString(8, eamCase.getExaminerPhone());
1820 if (
"".equals(eamCase.getNotes())) {
1821 bulkPs.setNull(9, Types.INTEGER);
1823 bulkPs.setString(9, eamCase.getNotes());
1831 if (counter >= bulkArtifactsThreshold) {
1832 bulkPs.executeBatch();
1837 bulkPs.executeBatch();
1838 }
catch (SQLException ex) {
1839 throw new CentralRepoException(
"Error inserting bulk cases.", ex);
1841 CentralRepoDbUtil.closeStatement(bulkPs);
1842 CentralRepoDbUtil.closeConnection(conn);
1856 public void updateAttributeInstanceComment(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1858 if (eamArtifact == null) {
1859 throw new CentralRepoException(
"CorrelationAttributeInstance is null");
1861 if (eamArtifact.getCorrelationCase() == null) {
1862 throw new CentralRepoException(
"Correlation case is null");
1864 if (eamArtifact.getCorrelationDataSource() == null) {
1865 throw new CentralRepoException(
"Correlation data source is null");
1867 Connection conn = connect();
1868 PreparedStatement preparedQuery = null;
1869 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1874 +
"WHERE case_id=? "
1875 +
"AND data_source_id=? "
1877 +
"AND file_path=?";
1880 preparedQuery = conn.prepareStatement(sqlUpdate);
1881 preparedQuery.setString(1, eamArtifact.getComment());
1882 preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID());
1883 preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID());
1884 preparedQuery.setString(4, eamArtifact.getCorrelationValue());
1885 preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
1886 preparedQuery.executeUpdate();
1887 }
catch (SQLException ex) {
1888 throw new CentralRepoException(
"Error getting/setting artifact instance comment=" + eamArtifact.getComment(), ex);
1890 CentralRepoDbUtil.closeStatement(preparedQuery);
1891 CentralRepoDbUtil.closeConnection(conn);
1910 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1911 CorrelationDataSource correlationDataSource,
long objectID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1913 if (correlationCase == null) {
1914 throw new CentralRepoException(
"Correlation case is null");
1917 Connection conn = connect();
1919 PreparedStatement preparedStatement = null;
1920 ResultSet resultSet = null;
1921 CorrelationAttributeInstance correlationAttributeInstance = null;
1925 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1927 =
"SELECT id, value, file_path, known_status, comment FROM "
1929 +
" WHERE case_id=?"
1930 +
" AND file_obj_id=?";
1932 preparedStatement = conn.prepareStatement(sql);
1933 preparedStatement.setInt(1, correlationCase.getID());
1934 preparedStatement.setInt(2, (
int) objectID);
1935 resultSet = preparedStatement.executeQuery();
1936 if (resultSet.next()) {
1937 int instanceId = resultSet.getInt(1);
1938 String value = resultSet.getString(2);
1939 String filePath = resultSet.getString(3);
1940 int knownStatus = resultSet.getInt(4);
1941 String comment = resultSet.getString(5);
1943 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1944 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
1946 }
catch (SQLException ex) {
1947 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1949 CentralRepoDbUtil.closeResultSet(resultSet);
1950 CentralRepoDbUtil.closeStatement(preparedStatement);
1951 CentralRepoDbUtil.closeConnection(conn);
1954 return correlationAttributeInstance;
1972 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1973 CorrelationDataSource correlationDataSource, String value, String filePath)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1975 if (correlationCase == null) {
1976 throw new CentralRepoException(
"Correlation case is null");
1978 if (correlationDataSource == null) {
1979 throw new CentralRepoException(
"Correlation data source is null");
1981 if (filePath == null) {
1982 throw new CentralRepoException(
"Correlation file path is null");
1985 Connection conn = connect();
1987 PreparedStatement preparedStatement = null;
1988 ResultSet resultSet = null;
1989 CorrelationAttributeInstance correlationAttributeInstance = null;
1992 String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
1994 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1996 =
"SELECT id, known_status, comment FROM "
1998 +
" WHERE case_id=?"
1999 +
" AND data_source_id=?"
2001 +
" AND file_path=?";
2003 preparedStatement = conn.prepareStatement(sql);
2004 preparedStatement.setInt(1, correlationCase.getID());
2005 preparedStatement.setInt(2, correlationDataSource.getID());
2006 preparedStatement.setString(3, normalizedValue);
2007 preparedStatement.setString(4, filePath.toLowerCase());
2008 resultSet = preparedStatement.executeQuery();
2009 if (resultSet.next()) {
2010 int instanceId = resultSet.getInt(1);
2011 int knownStatus = resultSet.getInt(2);
2012 String comment = resultSet.getString(3);
2014 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
2015 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
2017 }
catch (SQLException ex) {
2018 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2020 CentralRepoDbUtil.closeResultSet(resultSet);
2021 CentralRepoDbUtil.closeStatement(preparedStatement);
2022 CentralRepoDbUtil.closeConnection(conn);
2025 return correlationAttributeInstance;
2039 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws CentralRepoException {
2040 if (eamArtifact == null) {
2041 throw new CentralRepoException(
"CorrelationAttribute is null");
2043 if (knownStatus == null) {
2044 throw new CentralRepoException(
"Known status is null");
2047 if (eamArtifact.getCorrelationCase() == null) {
2048 throw new CentralRepoException(
"Correlation case is null");
2050 if (eamArtifact.getCorrelationDataSource() == null) {
2051 throw new CentralRepoException(
"Correlation data source is null");
2054 Connection conn = connect();
2056 PreparedStatement preparedUpdate = null;
2057 PreparedStatement preparedQuery = null;
2058 ResultSet resultSet = null;
2060 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
2065 +
" WHERE case_id=? "
2066 +
"AND data_source_id=? "
2068 +
"AND file_path=?";
2073 +
" SET known_status=? WHERE id=?";
2076 preparedQuery = conn.prepareStatement(sqlQuery);
2077 preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID());
2078 preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID());
2079 preparedQuery.setString(3, eamArtifact.getCorrelationValue());
2080 preparedQuery.setString(4, eamArtifact.getFilePath());
2081 resultSet = preparedQuery.executeQuery();
2082 if (resultSet.next()) {
2083 int instance_id = resultSet.getInt(
"id");
2084 preparedUpdate = conn.prepareStatement(sqlUpdate);
2086 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
2087 preparedUpdate.setInt(2, instance_id);
2089 preparedUpdate.executeUpdate();
2096 CorrelationCase correlationCaseWithId = getCaseByUUID(eamArtifact.getCorrelationCase().getCaseUUID());
2097 if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) {
2098 newDataSource(eamArtifact.getCorrelationDataSource());
2100 eamArtifact.setKnownStatus(knownStatus);
2101 addArtifactInstance(eamArtifact);
2104 }
catch (SQLException ex) {
2105 throw new CentralRepoException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
2107 CentralRepoDbUtil.closeResultSet(resultSet);
2108 CentralRepoDbUtil.closeStatement(preparedUpdate);
2109 CentralRepoDbUtil.closeStatement(preparedQuery);
2110 CentralRepoDbUtil.closeConnection(conn);
2123 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2125 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2127 Connection conn = connect();
2129 Long badInstances = 0L;
2130 PreparedStatement preparedStatement = null;
2131 ResultSet resultSet = null;
2133 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2135 =
"SELECT count(*) FROM "
2137 +
" WHERE value=? AND known_status=?";
2140 preparedStatement = conn.prepareStatement(sql);
2141 preparedStatement.setString(1, normalizedValue);
2142 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2143 resultSet = preparedStatement.executeQuery();
2145 badInstances = resultSet.getLong(1);
2146 }
catch (SQLException ex) {
2147 throw new CentralRepoException(
"Error getting count of notable artifact instances.", ex);
2149 CentralRepoDbUtil.closeResultSet(resultSet);
2150 CentralRepoDbUtil.closeStatement(preparedStatement);
2151 CentralRepoDbUtil.closeConnection(conn);
2154 return badInstances;
2170 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2172 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2174 Connection conn = connect();
2176 Collection<String> caseNames =
new LinkedHashSet<>();
2178 PreparedStatement preparedStatement = null;
2179 ResultSet resultSet = null;
2181 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2183 =
"SELECT DISTINCT case_name FROM "
2185 +
" INNER JOIN cases ON "
2187 +
".case_id=cases.id WHERE "
2191 +
".known_status=?";
2194 preparedStatement = conn.prepareStatement(sql);
2195 preparedStatement.setString(1, normalizedValue);
2196 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2197 resultSet = preparedStatement.executeQuery();
2198 while (resultSet.next()) {
2199 caseNames.add(resultSet.getString(
"case_name"));
2201 }
catch (SQLException ex) {
2202 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2204 CentralRepoDbUtil.closeResultSet(resultSet);
2205 CentralRepoDbUtil.closeStatement(preparedStatement);
2206 CentralRepoDbUtil.closeConnection(conn);
2209 return caseNames.stream().collect(Collectors.toList());
2225 public List<String> getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2227 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2229 Connection conn = connect();
2231 Collection<String> caseNames =
new LinkedHashSet<>();
2233 PreparedStatement preparedStatement = null;
2234 ResultSet resultSet = null;
2236 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2238 =
"SELECT DISTINCT case_name FROM "
2240 +
" INNER JOIN cases ON "
2242 +
".case_id=cases.id WHERE "
2247 preparedStatement = conn.prepareStatement(sql);
2248 preparedStatement.setString(1, normalizedValue);
2249 resultSet = preparedStatement.executeQuery();
2250 while (resultSet.next()) {
2251 caseNames.add(resultSet.getString(
"case_name"));
2253 }
catch (SQLException ex) {
2254 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2256 CentralRepoDbUtil.closeResultSet(resultSet);
2257 CentralRepoDbUtil.closeStatement(preparedStatement);
2258 CentralRepoDbUtil.closeConnection(conn);
2261 return caseNames.stream().collect(Collectors.toList());
2272 public void deleteReferenceSet(
int referenceSetID)
throws CentralRepoException {
2273 deleteReferenceSetEntries(referenceSetID);
2274 deleteReferenceSetEntry(referenceSetID);
2284 private void deleteReferenceSetEntry(
int referenceSetID)
throws CentralRepoException {
2285 Connection conn = connect();
2287 PreparedStatement preparedStatement = null;
2288 String sql =
"DELETE FROM reference_sets WHERE id=?";
2291 preparedStatement = conn.prepareStatement(sql);
2292 preparedStatement.setInt(1, referenceSetID);
2293 preparedStatement.executeUpdate();
2294 }
catch (SQLException ex) {
2295 throw new CentralRepoException(
"Error deleting reference set " + referenceSetID, ex);
2297 CentralRepoDbUtil.closeStatement(preparedStatement);
2298 CentralRepoDbUtil.closeConnection(conn);
2310 private void deleteReferenceSetEntries(
int referenceSetID)
throws CentralRepoException {
2311 Connection conn = connect();
2313 PreparedStatement preparedStatement = null;
2314 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2317 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
2320 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2321 preparedStatement.setInt(1, referenceSetID);
2322 preparedStatement.executeUpdate();
2323 }
catch (SQLException ex) {
2324 throw new CentralRepoException(
"Error deleting files from reference set " + referenceSetID, ex);
2326 CentralRepoDbUtil.closeStatement(preparedStatement);
2327 CentralRepoDbUtil.closeConnection(conn);
2345 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws CentralRepoException {
2346 CentralRepoFileSet refSet = this.getReferenceSetByID(referenceSetID);
2347 if (refSet == null) {
2351 return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
2366 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2367 return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
2371 public HashHitInfo lookupHash(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2372 int correlationTypeID = CorrelationAttributeInstance.FILES_TYPE_ID;
2373 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), hash);
2375 Connection conn = connect();
2377 PreparedStatement preparedStatement = null;
2378 ResultSet resultSet = null;
2379 String sql =
"SELECT value,comment FROM %s WHERE value=? AND reference_set_id=?";
2381 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2384 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2385 preparedStatement.setString(1, normalizeValued);
2386 preparedStatement.setInt(2, referenceSetID);
2387 resultSet = preparedStatement.executeQuery();
2388 if (resultSet.next()) {
2389 String comment = resultSet.getString(
"comment");
2390 String hashFound = resultSet.getString(
"value");
2391 HashHitInfo found =
new HashHitInfo(hashFound,
"",
"");
2392 found.addComment(comment);
2397 }
catch (SQLException ex) {
2398 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2400 CentralRepoDbUtil.closeResultSet(resultSet);
2401 CentralRepoDbUtil.closeStatement(preparedStatement);
2402 CentralRepoDbUtil.closeConnection(conn);
2416 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2418 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
2420 Connection conn = connect();
2422 Long matchingInstances = 0L;
2423 PreparedStatement preparedStatement = null;
2424 ResultSet resultSet = null;
2425 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2427 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2430 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2431 preparedStatement.setString(1, normalizeValued);
2432 preparedStatement.setInt(2, referenceSetID);
2433 resultSet = preparedStatement.executeQuery();
2435 matchingInstances = resultSet.getLong(1);
2436 }
catch (SQLException ex) {
2437 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2439 CentralRepoDbUtil.closeResultSet(resultSet);
2440 CentralRepoDbUtil.closeStatement(preparedStatement);
2441 CentralRepoDbUtil.closeConnection(conn);
2444 return 0 < matchingInstances;
2456 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2459 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
2462 if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
2466 Connection conn = connect();
2468 Long badInstances = 0L;
2469 PreparedStatement preparedStatement = null;
2470 ResultSet resultSet = null;
2471 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2474 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2475 preparedStatement.setString(1, normalizeValued);
2476 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2477 resultSet = preparedStatement.executeQuery();
2479 badInstances = resultSet.getLong(1);
2480 }
catch (SQLException ex) {
2481 throw new CentralRepoException(
"Error determining if artifact is notable by reference.", ex);
2483 CentralRepoDbUtil.closeResultSet(resultSet);
2484 CentralRepoDbUtil.closeStatement(preparedStatement);
2485 CentralRepoDbUtil.closeConnection(conn);
2488 return 0 < badInstances;
2500 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2502 throw new CentralRepoException(
"Correlation type is null");
2505 if (instanceTableCallback == null) {
2506 throw new CentralRepoException(
"Callback interface is null");
2509 Connection conn = connect();
2510 PreparedStatement preparedStatement = null;
2511 ResultSet resultSet = null;
2512 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2513 StringBuilder sql =
new StringBuilder();
2514 sql.append(
"select * from ");
2515 sql.append(tableName);
2518 preparedStatement = conn.prepareStatement(sql.toString());
2519 resultSet = preparedStatement.executeQuery();
2520 instanceTableCallback.process(resultSet);
2521 }
catch (SQLException ex) {
2522 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2524 CentralRepoDbUtil.closeResultSet(resultSet);
2525 CentralRepoDbUtil.closeStatement(preparedStatement);
2526 CentralRepoDbUtil.closeConnection(conn);
2540 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2542 throw new CentralRepoException(
"Correlation type is null");
2545 if (instanceTableCallback == null) {
2546 throw new CentralRepoException(
"Callback interface is null");
2549 if (whereClause == null) {
2550 throw new CentralRepoException(
"Where clause is null");
2553 Connection conn = connect();
2554 PreparedStatement preparedStatement = null;
2555 ResultSet resultSet = null;
2556 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2557 StringBuilder sql =
new StringBuilder(300);
2558 sql.append(
"select * from ")
2561 .append(whereClause);
2564 preparedStatement = conn.prepareStatement(sql.toString());
2565 resultSet = preparedStatement.executeQuery();
2566 instanceTableCallback.process(resultSet);
2567 }
catch (SQLException ex) {
2568 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2570 CentralRepoDbUtil.closeResultSet(resultSet);
2571 CentralRepoDbUtil.closeStatement(preparedStatement);
2572 CentralRepoDbUtil.closeConnection(conn);
2585 public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2587 if (instanceTableCallback == null) {
2588 throw new CentralRepoException(
"Callback interface is null");
2591 if (selectClause == null) {
2592 throw new CentralRepoException(
"Select clause is null");
2595 Connection conn = connect();
2596 PreparedStatement preparedStatement = null;
2597 ResultSet resultSet = null;
2598 StringBuilder sql =
new StringBuilder(300);
2599 sql.append(
"select ")
2600 .append(selectClause);
2603 preparedStatement = conn.prepareStatement(sql.toString());
2604 resultSet = preparedStatement.executeQuery();
2605 instanceTableCallback.process(resultSet);
2606 }
catch (SQLException ex) {
2607 throw new CentralRepoException(
"Error running query", ex);
2609 CentralRepoDbUtil.closeResultSet(resultSet);
2610 CentralRepoDbUtil.closeStatement(preparedStatement);
2611 CentralRepoDbUtil.closeConnection(conn);
2616 public void executeCommand(String sql, List<Object> params)
throws CentralRepoException {
2618 try (Connection conn = connect();) {
2620 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2623 if (params != null) {
2625 for (Object param : params) {
2626 preparedStatement.setObject(paramIndex, param);
2631 preparedStatement.executeUpdate();
2632 }
catch (SQLException ex) {
2633 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL %s", sql), ex);
2638 public void executeQuery(String sql, List<Object> params, CentralRepositoryDbQueryCallback queryCallback)
throws CentralRepoException {
2639 if (queryCallback == null) {
2640 throw new CentralRepoException(
"Query callback is null");
2643 try (Connection conn = connect();) {
2644 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2647 if (params != null) {
2649 for (Object param : params) {
2650 preparedStatement.setObject(paramIndex, param);
2655 try (ResultSet resultSet = preparedStatement.executeQuery();) {
2656 queryCallback.process(resultSet);
2658 }
catch (SQLException ex) {
2659 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL query %s", sql), ex);
2664 public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg)
throws CentralRepoException {
2665 if (eamOrg == null) {
2666 throw new CentralRepoException(
"EamOrganization is null");
2667 }
else if (eamOrg.getOrgID() != -1) {
2668 throw new CentralRepoException(
"EamOrganization already has an ID");
2671 Connection conn = connect();
2672 ResultSet generatedKeys = null;
2673 PreparedStatement preparedStatement = null;
2674 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2675 + getConflictClause();
2678 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2679 preparedStatement.setString(1, eamOrg.getName());
2680 preparedStatement.setString(2, eamOrg.getPocName());
2681 preparedStatement.setString(3, eamOrg.getPocEmail());
2682 preparedStatement.setString(4, eamOrg.getPocPhone());
2684 preparedStatement.executeUpdate();
2685 generatedKeys = preparedStatement.getGeneratedKeys();
2686 if (generatedKeys.next()) {
2687 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2690 throw new SQLException(
"Creating user failed, no ID obtained.");
2692 }
catch (SQLException ex) {
2693 throw new CentralRepoException(
"Error inserting new organization.", ex);
2695 CentralRepoDbUtil.closeResultSet(generatedKeys);
2696 CentralRepoDbUtil.closeStatement(preparedStatement);
2697 CentralRepoDbUtil.closeConnection(conn);
2709 public List<CentralRepoOrganization> getOrganizations() throws CentralRepoException {
2710 Connection conn = connect();
2712 List<CentralRepoOrganization> orgs =
new ArrayList<>();
2713 PreparedStatement preparedStatement = null;
2714 ResultSet resultSet = null;
2715 String sql =
"SELECT * FROM organizations";
2718 preparedStatement = conn.prepareStatement(sql);
2719 resultSet = preparedStatement.executeQuery();
2720 while (resultSet.next()) {
2721 orgs.add(getEamOrganizationFromResultSet(resultSet));
2725 }
catch (SQLException ex) {
2726 throw new CentralRepoException(
"Error getting all organizations.", ex);
2728 CentralRepoDbUtil.closeResultSet(resultSet);
2729 CentralRepoDbUtil.closeStatement(preparedStatement);
2730 CentralRepoDbUtil.closeConnection(conn);
2744 public CentralRepoOrganization getOrganizationByID(
int orgID)
throws CentralRepoException {
2745 Connection conn = connect();
2747 PreparedStatement preparedStatement = null;
2748 ResultSet resultSet = null;
2749 String sql =
"SELECT * FROM organizations WHERE id=?";
2752 preparedStatement = conn.prepareStatement(sql);
2753 preparedStatement.setInt(1, orgID);
2754 resultSet = preparedStatement.executeQuery();
2756 return getEamOrganizationFromResultSet(resultSet);
2758 }
catch (SQLException ex) {
2759 throw new CentralRepoException(
"Error getting organization by id.", ex);
2761 CentralRepoDbUtil.closeResultSet(resultSet);
2762 CentralRepoDbUtil.closeStatement(preparedStatement);
2763 CentralRepoDbUtil.closeConnection(conn);
2777 public CentralRepoOrganization getReferenceSetOrganization(
int referenceSetID)
throws CentralRepoException {
2779 CentralRepoFileSet globalSet = getReferenceSetByID(referenceSetID);
2780 if (globalSet == null) {
2781 throw new CentralRepoException(
"Reference set with ID " + referenceSetID +
" not found");
2783 return (getOrganizationByID(globalSet.getOrgID()));
2793 private void testArgument(CentralRepoOrganization
org)
throws CentralRepoException {
2795 throw new CentralRepoException(
"EamOrganization is null");
2796 }
else if (
org.getOrgID() == -1) {
2797 throw new CentralRepoException(
"Organization has -1 row ID");
2813 public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName)
throws CentralRepoException {
2815 String querySQL =
"SELECT * FROM examiners WHERE login_name = '" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"'";
2816 try (Connection connection = connect();
2817 Statement statement = connection.createStatement();
2818 ResultSet resultSet = statement.executeQuery(querySQL);) {
2820 if (resultSet.next()) {
2821 return new CentralRepoExaminer(resultSet.getLong(
"id"), resultSet.getString(
"login_name"));
2826 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
2828 insertSQL =
"INSERT INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')" + getConflictClause();
2831 insertSQL =
"INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')";
2834 throw new CentralRepoException(String.format(
"Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
2836 statement.execute(insertSQL);
2839 try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
2840 if (resultSet2.next()) {
2841 return new CentralRepoExaminer(resultSet2.getLong(
"id"), resultSet2.getString(
"login_name"));
2843 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName);
2847 }
catch (SQLException ex) {
2848 throw new CentralRepoException(
"Error inserting row in examiners", ex);
2852 }
catch (SQLException ex) {
2853 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName, ex);
2866 public void updateOrganization(CentralRepoOrganization updatedOrganization)
throws CentralRepoException {
2867 testArgument(updatedOrganization);
2869 Connection conn = connect();
2870 PreparedStatement preparedStatement = null;
2871 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2873 preparedStatement = conn.prepareStatement(sql);
2874 preparedStatement.setString(1, updatedOrganization.getName());
2875 preparedStatement.setString(2, updatedOrganization.getPocName());
2876 preparedStatement.setString(3, updatedOrganization.getPocEmail());
2877 preparedStatement.setString(4, updatedOrganization.getPocPhone());
2878 preparedStatement.setInt(5, updatedOrganization.getOrgID());
2879 preparedStatement.executeUpdate();
2880 }
catch (SQLException ex) {
2881 throw new CentralRepoException(
"Error updating organization.", ex);
2883 CentralRepoDbUtil.closeStatement(preparedStatement);
2884 CentralRepoDbUtil.closeConnection(conn);
2889 public void deleteOrganization(CentralRepoOrganization organizationToDelete)
throws CentralRepoException {
2890 testArgument(organizationToDelete);
2892 Connection conn = connect();
2893 PreparedStatement checkIfUsedStatement = null;
2894 ResultSet resultSet = null;
2895 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2896 PreparedStatement deleteOrgStatement = null;
2897 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2899 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2900 checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
2901 checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
2902 resultSet = checkIfUsedStatement.executeQuery();
2904 if (resultSet.getLong(1) > 0) {
2905 throw new CentralRepoException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2907 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2908 deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
2909 deleteOrgStatement.executeUpdate();
2910 }
catch (SQLException ex) {
2911 throw new CentralRepoException(
"Error executing query when attempting to delete organization by id.", ex);
2913 CentralRepoDbUtil.closeResultSet(resultSet);
2914 CentralRepoDbUtil.closeStatement(checkIfUsedStatement);
2915 CentralRepoDbUtil.closeStatement(deleteOrgStatement);
2916 CentralRepoDbUtil.closeConnection(conn);
2930 public int newReferenceSet(CentralRepoFileSet eamGlobalSet)
throws CentralRepoException {
2931 if (eamGlobalSet == null) {
2932 throw new CentralRepoException(
"EamGlobalSet is null");
2935 if (eamGlobalSet.getFileKnownStatus() == null) {
2936 throw new CentralRepoException(
"File known status on the EamGlobalSet is null");
2939 if (eamGlobalSet.getType() == null) {
2940 throw new CentralRepoException(
"Type on the EamGlobalSet is null");
2943 Connection conn = connect();
2945 PreparedStatement preparedStatement1 = null;
2946 PreparedStatement preparedStatement2 = null;
2947 ResultSet resultSet = null;
2948 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2949 + getConflictClause();
2950 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2953 preparedStatement1 = conn.prepareStatement(sql1);
2954 preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
2955 preparedStatement1.setString(2, eamGlobalSet.getSetName());
2956 preparedStatement1.setString(3, eamGlobalSet.getVersion());
2957 preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
2958 preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
2959 preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
2960 preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
2962 preparedStatement1.executeUpdate();
2964 preparedStatement2 = conn.prepareStatement(sql2);
2965 preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
2966 preparedStatement2.setString(2, eamGlobalSet.getSetName());
2967 preparedStatement2.setString(3, eamGlobalSet.getVersion());
2968 preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
2970 resultSet = preparedStatement2.executeQuery();
2972 return resultSet.getInt(
"id");
2974 }
catch (SQLException ex) {
2975 throw new CentralRepoException(
"Error inserting new global set.", ex);
2977 CentralRepoDbUtil.closeResultSet(resultSet);
2978 CentralRepoDbUtil.closeStatement(preparedStatement1);
2979 CentralRepoDbUtil.closeStatement(preparedStatement2);
2980 CentralRepoDbUtil.closeConnection(conn);
2994 public CentralRepoFileSet getReferenceSetByID(
int referenceSetID)
throws CentralRepoException {
2995 Connection conn = connect();
2997 PreparedStatement preparedStatement1 = null;
2998 ResultSet resultSet = null;
2999 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
3002 preparedStatement1 = conn.prepareStatement(sql1);
3003 preparedStatement1.setInt(1, referenceSetID);
3004 resultSet = preparedStatement1.executeQuery();
3005 if (resultSet.next()) {
3006 return getEamGlobalSetFromResultSet(resultSet);
3011 }
catch (SQLException ex) {
3012 throw new CentralRepoException(
"Error getting reference set by id.", ex);
3014 CentralRepoDbUtil.closeResultSet(resultSet);
3015 CentralRepoDbUtil.closeStatement(preparedStatement1);
3016 CentralRepoDbUtil.closeConnection(conn);
3030 public List<CentralRepoFileSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3032 if (correlationType == null) {
3033 throw new CentralRepoException(
"Correlation type is null");
3036 List<CentralRepoFileSet> results =
new ArrayList<>();
3037 Connection conn = connect();
3039 PreparedStatement preparedStatement1 = null;
3040 ResultSet resultSet = null;
3041 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
3044 preparedStatement1 = conn.prepareStatement(sql1);
3045 resultSet = preparedStatement1.executeQuery();
3046 while (resultSet.next()) {
3047 results.add(getEamGlobalSetFromResultSet(resultSet));
3050 }
catch (SQLException ex) {
3051 throw new CentralRepoException(
"Error getting reference sets.", ex);
3053 CentralRepoDbUtil.closeResultSet(resultSet);
3054 CentralRepoDbUtil.closeStatement(preparedStatement1);
3055 CentralRepoDbUtil.closeConnection(conn);
3070 public void addReferenceInstance(CentralRepoFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3071 if (eamGlobalFileInstance.getKnownStatus() == null) {
3072 throw new CentralRepoException(
"Known status of EamGlobalFileInstance is null");
3074 if (correlationType == null) {
3075 throw new CentralRepoException(
"Correlation type is null");
3078 Connection conn = connect();
3080 PreparedStatement preparedStatement = null;
3082 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3083 + getConflictClause();
3086 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(correlationType)));
3087 preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
3088 preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
3089 preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
3090 preparedStatement.setString(4, eamGlobalFileInstance.getComment());
3091 preparedStatement.executeUpdate();
3092 }
catch (SQLException ex) {
3093 throw new CentralRepoException(
"Error inserting new reference instance into reference_ table.", ex);
3095 CentralRepoDbUtil.closeStatement(preparedStatement);
3096 CentralRepoDbUtil.closeConnection(conn);
3113 public boolean referenceSetExists(String referenceSetName, String version)
throws CentralRepoException {
3114 Connection conn = connect();
3116 PreparedStatement preparedStatement1 = null;
3117 ResultSet resultSet = null;
3118 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
3121 preparedStatement1 = conn.prepareStatement(sql1);
3122 preparedStatement1.setString(1, referenceSetName);
3123 preparedStatement1.setString(2, version);
3124 resultSet = preparedStatement1.executeQuery();
3125 return (resultSet.next());
3127 }
catch (SQLException ex) {
3128 throw new CentralRepoException(
"Error testing whether reference set exists (name: " + referenceSetName
3129 +
" version: " + version, ex);
3131 CentralRepoDbUtil.closeResultSet(resultSet);
3132 CentralRepoDbUtil.closeStatement(preparedStatement1);
3133 CentralRepoDbUtil.closeConnection(conn);
3143 public void bulkInsertReferenceTypeEntries(Set<CentralRepoFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws CentralRepoException {
3144 if (contentType == null) {
3145 throw new CentralRepoException(
"Correlation type is null");
3147 if (globalInstances == null) {
3148 throw new CentralRepoException(
"Null set of EamGlobalFileInstance");
3151 Connection conn = connect();
3153 PreparedStatement bulkPs = null;
3155 conn.setAutoCommit(
false);
3158 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3159 + getConflictClause();
3161 bulkPs = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(contentType)));
3163 for (CentralRepoFileInstance globalInstance : globalInstances) {
3164 if (globalInstance.getKnownStatus() == null) {
3165 throw new CentralRepoException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
3168 bulkPs.setInt(1, globalInstance.getGlobalSetID());
3169 bulkPs.setString(2, globalInstance.getMD5Hash());
3170 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
3171 bulkPs.setString(4, globalInstance.getComment());
3175 bulkPs.executeBatch();
3177 }
catch (SQLException | CentralRepoException ex) {
3180 }
catch (SQLException ex2) {
3183 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
3185 CentralRepoDbUtil.closeStatement(bulkPs);
3186 CentralRepoDbUtil.closeConnection(conn);
3201 public List<CentralRepoFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws CentralRepoException, CorrelationAttributeNormalizationException {
3202 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
3204 Connection conn = connect();
3206 List<CentralRepoFileInstance> globalFileInstances =
new ArrayList<>();
3207 PreparedStatement preparedStatement1 = null;
3208 ResultSet resultSet = null;
3209 String sql1 =
"SELECT * FROM %s WHERE value=?";
3212 preparedStatement1 = conn.prepareStatement(String.format(sql1, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
3213 preparedStatement1.setString(1, normalizeValued);
3214 resultSet = preparedStatement1.executeQuery();
3215 while (resultSet.next()) {
3216 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
3219 }
catch (SQLException ex) {
3220 throw new CentralRepoException(
"Error getting reference instances by type and value.", ex);
3222 CentralRepoDbUtil.closeResultSet(resultSet);
3223 CentralRepoDbUtil.closeStatement(preparedStatement1);
3224 CentralRepoDbUtil.closeConnection(conn);
3227 return globalFileInstances;
3240 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3241 if (newType == null) {
3242 throw new CentralRepoException(
"Correlation type is null");
3245 if (-1 == newType.getId()) {
3246 typeId = newCorrelationTypeNotKnownId(newType);
3248 typeId = newCorrelationTypeKnownId(newType);
3251 synchronized (typeCache) {
3252 typeCache.put(newType.getId(), newType);
3267 public int newCorrelationTypeNotKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3268 Connection conn = connect();
3270 PreparedStatement preparedStatement = null;
3271 PreparedStatement preparedStatementQuery = null;
3272 ResultSet resultSet = null;
3277 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
3279 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3282 preparedStatement = conn.prepareStatement(insertSql);
3284 preparedStatement.setString(1, newType.getDisplayName());
3285 preparedStatement.setString(2, newType.getDbTableName());
3286 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
3287 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
3289 preparedStatement.executeUpdate();
3291 preparedStatementQuery = conn.prepareStatement(querySql);
3292 preparedStatementQuery.setString(1, newType.getDisplayName());
3293 preparedStatementQuery.setString(2, newType.getDbTableName());
3295 resultSet = preparedStatementQuery.executeQuery();
3296 if (resultSet.next()) {
3297 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3298 typeId = correlationType.getId();
3300 }
catch (SQLException ex) {
3301 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3303 CentralRepoDbUtil.closeResultSet(resultSet);
3304 CentralRepoDbUtil.closeStatement(preparedStatement);
3305 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3306 CentralRepoDbUtil.closeConnection(conn);
3320 private int newCorrelationTypeKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3321 Connection conn = connect();
3323 PreparedStatement preparedStatement = null;
3324 PreparedStatement preparedStatementQuery = null;
3325 ResultSet resultSet = null;
3330 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3332 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3335 preparedStatement = conn.prepareStatement(insertSql);
3337 preparedStatement.setInt(1, newType.getId());
3338 preparedStatement.setString(2, newType.getDisplayName());
3339 preparedStatement.setString(3, newType.getDbTableName());
3340 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
3341 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
3343 preparedStatement.executeUpdate();
3345 preparedStatementQuery = conn.prepareStatement(querySql);
3346 preparedStatementQuery.setString(1, newType.getDisplayName());
3347 preparedStatementQuery.setString(2, newType.getDbTableName());
3349 resultSet = preparedStatementQuery.executeQuery();
3350 if (resultSet.next()) {
3351 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3352 typeId = correlationType.getId();
3354 }
catch (SQLException ex) {
3355 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3357 CentralRepoDbUtil.closeResultSet(resultSet);
3358 CentralRepoDbUtil.closeStatement(preparedStatement);
3359 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3360 CentralRepoDbUtil.closeConnection(conn);
3366 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws CentralRepoException {
3368 synchronized (typeCache) {
3369 if (isCRTypeCacheInitialized ==
false) {
3370 getCorrelationTypesFromCr();
3372 return new ArrayList<>(typeCache.asMap().values());
3386 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws CentralRepoException {
3387 Connection conn = connect();
3389 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3390 PreparedStatement preparedStatement = null;
3391 ResultSet resultSet = null;
3392 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3395 preparedStatement = conn.prepareStatement(sql);
3396 resultSet = preparedStatement.executeQuery();
3397 while (resultSet.next()) {
3398 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3402 }
catch (SQLException ex) {
3403 throw new CentralRepoException(
"Error getting enabled correlation types.", ex);
3405 CentralRepoDbUtil.closeResultSet(resultSet);
3406 CentralRepoDbUtil.closeStatement(preparedStatement);
3407 CentralRepoDbUtil.closeConnection(conn);
3421 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws CentralRepoException {
3422 Connection conn = connect();
3424 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3425 PreparedStatement preparedStatement = null;
3426 ResultSet resultSet = null;
3427 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3430 preparedStatement = conn.prepareStatement(sql);
3431 resultSet = preparedStatement.executeQuery();
3432 while (resultSet.next()) {
3433 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3437 }
catch (SQLException ex) {
3438 throw new CentralRepoException(
"Error getting supported correlation types.", ex);
3440 CentralRepoDbUtil.closeResultSet(resultSet);
3441 CentralRepoDbUtil.closeStatement(preparedStatement);
3442 CentralRepoDbUtil.closeConnection(conn);
3454 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws CentralRepoException {
3455 Connection conn = connect();
3457 PreparedStatement preparedStatement = null;
3458 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3461 preparedStatement = conn.prepareStatement(sql);
3462 preparedStatement.setString(1, aType.getDisplayName());
3463 preparedStatement.setString(2, aType.getDbTableName());
3464 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3465 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3466 preparedStatement.setInt(5, aType.getId());
3467 preparedStatement.executeUpdate();
3468 synchronized (typeCache) {
3469 typeCache.put(aType.getId(), aType);
3471 }
catch (SQLException ex) {
3472 throw new CentralRepoException(
"Error updating correlation type.", ex);
3474 CentralRepoDbUtil.closeStatement(preparedStatement);
3475 CentralRepoDbUtil.closeConnection(conn);
3490 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws CentralRepoException {
3492 synchronized (typeCache) {
3493 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3495 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3498 }
catch (ExecutionException ex) {
3499 throw new CentralRepoException(
"Error getting correlation type", ex);
3512 private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(
int typeId)
throws CentralRepoException {
3513 Connection conn = connect();
3515 CorrelationAttributeInstance.Type aType;
3516 PreparedStatement preparedStatement = null;
3517 ResultSet resultSet = null;
3518 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3521 preparedStatement = conn.prepareStatement(sql);
3522 preparedStatement.setInt(1, typeId);
3523 resultSet = preparedStatement.executeQuery();
3524 if (resultSet.next()) {
3525 aType = getCorrelationTypeFromResultSet(resultSet);
3528 throw new CentralRepoException(
"Failed to find entry for correlation type ID = " + typeId);
3531 }
catch (SQLException ex) {
3532 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
3534 CentralRepoDbUtil.closeResultSet(resultSet);
3535 CentralRepoDbUtil.closeStatement(preparedStatement);
3536 CentralRepoDbUtil.closeConnection(conn);
3546 private void getCorrelationTypesFromCr() throws CentralRepoException {
3549 synchronized (typeCache) {
3550 typeCache.invalidateAll();
3551 isCRTypeCacheInitialized =
false;
3554 String sql =
"SELECT * FROM correlation_types";
3555 try (Connection conn = connect();
3556 PreparedStatement preparedStatement = conn.prepareStatement(sql);
3557 ResultSet resultSet = preparedStatement.executeQuery();) {
3559 synchronized (typeCache) {
3560 while (resultSet.next()) {
3561 CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
3562 typeCache.put(aType.getId(), aType);
3564 isCRTypeCacheInitialized =
true;
3566 }
catch (SQLException ex) {
3567 throw new CentralRepoException(
"Error getting correlation types.", ex);
3581 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3582 if (null == resultSet) {
3586 CentralRepoOrganization eamOrg = null;
3588 resultSet.getInt(
"org_id");
3589 if (!resultSet.wasNull()) {
3591 eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3592 resultSet.getString(
"org_name"),
3593 resultSet.getString(
"poc_name"),
3594 resultSet.getString(
"poc_email"),
3595 resultSet.getString(
"poc_phone"));
3598 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3599 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3600 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3605 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3606 if (null == resultSet) {
3610 CorrelationDataSource eamDataSource =
new CorrelationDataSource(
3611 resultSet.getInt(
"case_id"),
3612 resultSet.getInt(
"id"),
3613 resultSet.getString(
"device_id"),
3614 resultSet.getString(
"name"),
3615 resultSet.getLong(
"datasource_obj_id"),
3616 resultSet.getString(
"md5"),
3617 resultSet.getString(
"sha1"),
3618 resultSet.getString(
"sha256")
3621 return eamDataSource;
3624 private CorrelationAttributeInstance.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
throws CentralRepoException, SQLException {
3625 if (null == resultSet) {
3629 CorrelationAttributeInstance.Type eamArtifactType =
new CorrelationAttributeInstance.Type(
3630 resultSet.getInt(
"id"),
3631 resultSet.getString(
"display_name"),
3632 resultSet.getString(
"db_table_name"),
3633 resultSet.getBoolean(
"supported"),
3634 resultSet.getBoolean(
"enabled")
3637 return eamArtifactType;
3650 private CorrelationAttributeInstance getCorrAttrFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3651 if (null == resultSet) {
3655 CentralRepoOrganization eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3656 resultSet.getString(
"org_name"),
3657 resultSet.getString(
"poc_name"),
3658 resultSet.getString(
"poc_email"),
3659 resultSet.getString(
"poc_phone"));
3661 return new CorrelationAttributeInstance(
3663 resultSet.getString(
"value"),
3664 resultSet.getInt(
"instance_id"),
3665 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3666 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3667 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3668 new CorrelationDataSource(
3669 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3670 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3671 resultSet.getString(
"file_path"),
3672 resultSet.getString(
"comment"),
3673 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3674 resultSet.getLong(
"file_obj_id"));
3677 private CentralRepoOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3678 if (null == resultSet) {
3682 return new CentralRepoOrganization(
3683 resultSet.getInt(
"id"),
3684 resultSet.getString(
"org_name"),
3685 resultSet.getString(
"poc_name"),
3686 resultSet.getString(
"poc_email"),
3687 resultSet.getString(
"poc_phone")
3691 private CentralRepoFileSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException {
3692 if (null == resultSet) {
3696 return new CentralRepoFileSet(
3697 resultSet.getInt(
"id"),
3698 resultSet.getInt(
"org_id"),
3699 resultSet.getString(
"set_name"),
3700 resultSet.getString(
"version"),
3701 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3702 resultSet.getBoolean(
"read_only"),
3703 CentralRepository.getInstance().getCorrelationTypeById(resultSet.getInt(
"type")),
3704 LocalDate.parse(resultSet.getString(
"import_date"))
3708 private CentralRepoFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3709 if (null == resultSet) {
3713 return new CentralRepoFileInstance(
3714 resultSet.getInt(
"id"),
3715 resultSet.getInt(
"reference_set_id"),
3716 resultSet.getString(
"value"),
3717 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3718 resultSet.getString(
"comment")
3722 private String getPlatformSpecificInsertSQL(String sql)
throws CentralRepoException {
3724 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
3726 return "INSERT " + sql +
" ON CONFLICT DO NOTHING";
3728 return "INSERT OR IGNORE " + sql;
3731 throw new CentralRepoException(
"Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform());
3745 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3752 @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.",
3753 "# {0} - minorVersion",
3754 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3755 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3756 "# {0} - majorVersion",
3757 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3758 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3759 "# {0} - platformName",
3760 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3762 public void upgradeSchema() throws CentralRepoException, SQLException, IncompatibleCentralRepoException {
3764 ResultSet resultSet = null;
3765 Statement statement = null;
3766 PreparedStatement preparedStatement = null;
3767 Connection conn = null;
3768 CentralRepoPlatforms selectedPlatform = null;
3771 conn = connect(
false);
3772 conn.setAutoCommit(
false);
3773 statement = conn.createStatement();
3774 selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
3775 int minorVersion = 0;
3776 String minorVersionStr = null;
3777 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"'");
3778 if (resultSet.next()) {
3779 minorVersionStr = resultSet.getString(
"value");
3781 minorVersion = Integer.parseInt(minorVersionStr);
3782 }
catch (NumberFormatException ex) {
3783 throw new CentralRepoException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3786 throw new CentralRepoException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3789 int majorVersion = 0;
3790 String majorVersionStr = null;
3791 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"'");
3792 if (resultSet.next()) {
3793 majorVersionStr = resultSet.getString(
"value");
3795 majorVersion = Integer.parseInt(majorVersionStr);
3796 }
catch (NumberFormatException ex) {
3797 throw new CentralRepoException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3800 throw new CentralRepoException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3811 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3816 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3817 throw new IncompatibleCentralRepoException(Bundle.AbstractSqlEamDb_upgradeSchema_incompatible());
3819 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3820 logger.log(Level.INFO,
"Central Repository is up to date");
3823 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3824 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3831 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3832 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3833 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3834 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3839 CentralRepoDbUtil.insertDefaultOrganization(conn);
3845 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3846 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3848 final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
3849 final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
3850 final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
3851 final String addValueIndexTemplate = RdbmsCentralRepoFactory.getAddValueIndexTemplate();
3852 final String addKnownStatusIndexTemplate = RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate();
3853 final String addObjectIdIndexTemplate = RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate();
3855 final String addAttributeSql;
3857 switch (selectedPlatform) {
3859 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3862 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3865 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3868 final String dataSourcesTableName =
"data_sources";
3869 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3870 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3871 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3873 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3874 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3875 List<String> instaceTablesToAdd =
new ArrayList<>();
3877 final String wirelessNetworksDbTableName =
"wireless_networks";
3878 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3879 final String macAddressDbTableName =
"mac_address";
3880 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3881 final String imeiNumberDbTableName =
"imei_number";
3882 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3883 final String iccidNumberDbTableName =
"iccid_number";
3884 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3885 final String imsiNumberDbTableName =
"imsi_number";
3886 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3889 preparedStatement = conn.prepareStatement(addAttributeSql);
3890 preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID);
3891 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3892 preparedStatement.setString(3, wirelessNetworksDbTableName);
3893 preparedStatement.setInt(4, 1);
3894 preparedStatement.setInt(5, 1);
3895 preparedStatement.execute();
3898 preparedStatement = conn.prepareStatement(addAttributeSql);
3899 preparedStatement.setInt(1, CorrelationAttributeInstance.MAC_TYPE_ID);
3900 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3901 preparedStatement.setString(3, macAddressDbTableName);
3902 preparedStatement.setInt(4, 1);
3903 preparedStatement.setInt(5, 1);
3904 preparedStatement.execute();
3907 preparedStatement = conn.prepareStatement(addAttributeSql);
3908 preparedStatement.setInt(1, CorrelationAttributeInstance.IMEI_TYPE_ID);
3909 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3910 preparedStatement.setString(3, imeiNumberDbTableName);
3911 preparedStatement.setInt(4, 1);
3912 preparedStatement.setInt(5, 1);
3913 preparedStatement.execute();
3916 preparedStatement = conn.prepareStatement(addAttributeSql);
3917 preparedStatement.setInt(1, CorrelationAttributeInstance.IMSI_TYPE_ID);
3918 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3919 preparedStatement.setString(3, imsiNumberDbTableName);
3920 preparedStatement.setInt(4, 1);
3921 preparedStatement.setInt(5, 1);
3922 preparedStatement.execute();
3925 preparedStatement = conn.prepareStatement(addAttributeSql);
3926 preparedStatement.setInt(1, CorrelationAttributeInstance.ICCID_TYPE_ID);
3927 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3928 preparedStatement.setString(3, iccidNumberDbTableName);
3929 preparedStatement.setInt(4, 1);
3930 preparedStatement.setInt(5, 1);
3931 preparedStatement.execute();
3934 for (String tableName : instaceTablesToAdd) {
3935 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3936 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3937 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3938 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3939 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3943 String instance_type_dbname;
3944 final String objectIdColumnName =
"file_obj_id";
3945 for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
3946 instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
3947 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3948 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3950 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3956 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3957 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3959 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3960 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3962 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3963 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3974 String creationMajorVer;
3975 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3976 if (resultSet.next()) {
3977 creationMajorVer = resultSet.getString(
"value");
3979 creationMajorVer =
"0";
3981 String creationMinorVer;
3982 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3983 if (resultSet.next()) {
3984 creationMinorVer = resultSet.getString(
"value");
3986 creationMinorVer =
"0";
3988 statement.execute(
"DROP TABLE db_info");
3989 if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) {
3990 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3992 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3994 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3995 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3996 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3997 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
4002 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
4003 switch (selectedPlatform) {
4005 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
4007 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
4011 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
4012 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
4013 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
4015 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
4016 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
4017 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
4018 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
4019 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
4020 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesNameIndexStatement());
4021 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesObjectIdIndexStatement());
4022 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
4023 statement.execute(
"DROP TABLE old_data_sources");
4026 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
4031 (
new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
4034 (
new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);
4037 (
new CentralRepoDbUpgrader15To16()).upgradeSchema(dbSchemaVersion, conn);
4039 updateSchemaVersion(conn);
4041 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
4042 }
catch (SQLException | CentralRepoException ex) {
4047 }
catch (SQLException ex2) {
4048 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
4052 CentralRepoDbUtil.closeResultSet(resultSet);
4053 CentralRepoDbUtil.closeStatement(preparedStatement);
4054 CentralRepoDbUtil.closeStatement(statement);
4055 CentralRepoDbUtil.closeConnection(conn);
CentralRepoAccount getAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)