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.closeStatement(preparedStatement);
216 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
509 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
569 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
606 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
791 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
855 CentralRepoDbUtil.closeResultSet(resultSet);
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.closeStatement(preparedStatement);
889 CentralRepoDbUtil.closeResultSet(resultSet);
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()));
1103 try (Connection connection = connect();
1104 PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);) {
1106 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1107 preparedStatement.setString(2, normalizedAccountID);
1109 preparedStatement.executeUpdate();
1112 return getAccount(crAccountType, normalizedAccountID);
1113 }
catch (SQLException ex) {
1114 throw new CentralRepoException(
"Error adding an account to CR database.", ex);
1119 public Optional<CentralRepoAccountType> getAccountTypeByName(String accountTypeName)
throws CentralRepoException {
1121 return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName));
1122 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
1123 throw new CentralRepoException(
"Error looking up CR account type in cache.", ex);
1128 public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException {
1130 Collection<CentralRepoAccountType> accountTypes =
new ArrayList<>();
1132 String sql =
"SELECT * FROM account_types";
1133 try (Connection conn = connect();
1134 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1136 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1137 while (resultSet.next()) {
1138 Account.Type acctType =
new Account.Type(resultSet.getString(
"type_name"), resultSet.getString(
"display_name"));
1139 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1141 accountTypes.add(crAccountType);
1144 }
catch (SQLException ex) {
1145 throw new CentralRepoException(
"Error getting account types from central repository.", ex);
1147 return accountTypes;
1159 private Optional<CentralRepoAccountType> getCRAccountTypeFromDb(String accountTypeName)
throws CentralRepoException {
1161 String sql =
"SELECT * FROM account_types WHERE type_name = ?";
1162 try (Connection conn = connect();
1163 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1165 preparedStatement.setString(1, accountTypeName);
1166 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1167 if (resultSet.next()) {
1168 Account.Type acctType =
new Account.Type(accountTypeName, resultSet.getString(
"display_name"));
1169 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1170 accountTypesCache.put(accountTypeName, Optional.of(crAccountType));
1171 return Optional.of(crAccountType);
1173 accountTypesCache.put(accountTypeName, Optional.empty());
1174 return Optional.empty();
1177 }
catch (SQLException ex) {
1178 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
1200 public CentralRepoAccount
getAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws InvalidAccountIDException, CentralRepoException {
1201 String normalizedAccountID = CentralRepoAccount.normalizeAccountIdentifier(crAccountType, accountUniqueID);
1202 CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, normalizedAccountID));
1203 if (crAccount == null) {
1204 crAccount = getCRAccountFromDb(crAccountType, normalizedAccountID);
1205 if (crAccount != null) {
1206 accountsCache.put(Pair.of(crAccountType, normalizedAccountID), crAccount);
1225 private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1227 CentralRepoAccount account = null;
1229 String sql =
"SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
1230 try (Connection connection = connect();
1231 PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
1233 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1234 preparedStatement.setString(2, accountUniqueID);
1236 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1237 if (resultSet.next()) {
1238 account =
new CentralRepoAccount(resultSet.getInt(
"id"), crAccountType, resultSet.getString(
"account_unique_identifier"));
1241 }
catch (SQLException ex) {
1242 throw new CentralRepoException(
"Error getting account type id", ex);
1248 private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1249 if (eamArtifact == null) {
1250 throw new CentralRepoException(
"CorrelationAttribute is null");
1252 if (eamArtifact.getCorrelationType() == null) {
1253 throw new CentralRepoException(
"Correlation type is null");
1255 if (eamArtifact.getCorrelationValue() == null) {
1256 throw new CentralRepoException(
"Correlation value is null");
1258 if (eamArtifact.getCorrelationValue().length() >= MAX_VALUE_LENGTH) {
1259 throw new CentralRepoException(
"Artifact value too long for central repository."
1260 +
"\nCorrelationArtifact ID: " + eamArtifact.getID()
1261 +
"\nCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1262 +
"\nCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1265 if (eamArtifact.getCorrelationCase() == null) {
1266 throw new CentralRepoException(
"CorrelationAttributeInstance case is null");
1268 if (eamArtifact.getCorrelationDataSource() == null) {
1269 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null");
1271 if (eamArtifact.getKnownStatus() == null) {
1272 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null");
1277 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1278 if (value == null) {
1279 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null value");
1281 return getArtifactInstancesByTypeValues(aType, Arrays.asList(value));
1285 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValues(CorrelationAttributeInstance.Type aType, List<String> values)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1286 if (aType == null) {
1287 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1289 if (values == null || values.isEmpty()) {
1290 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1292 return getArtifactInstances(prepareGetInstancesSql(aType, values), aType);
1296 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValuesAndCases(CorrelationAttributeInstance.Type aType, List<String> values, List<Integer> caseIds)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1297 if (aType == null) {
1298 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1300 if (values == null || values.isEmpty()) {
1301 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1303 if (caseIds == null || caseIds.isEmpty()) {
1304 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified cases");
1306 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1311 StringBuilder inValuesBuilder =
new StringBuilder(prepareGetInstancesSql(aType, values));
1312 inValuesBuilder.append(sql);
1313 inValuesBuilder.append(caseIds.stream().map(String::valueOf).collect(Collectors.joining(
"', '")));
1314 inValuesBuilder.append(
"')");
1315 return getArtifactInstances(inValuesBuilder.toString(), aType);
1330 private String prepareGetInstancesSql(CorrelationAttributeInstance.Type aType, List<String> values)
throws CorrelationAttributeNormalizationException {
1331 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1335 +
".id as instance_id,"
1340 +
" cases.*, organizations.org_name, organizations.poc_name, organizations.poc_email, organizations.poc_phone, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.datasource_obj_id, data_sources.md5, data_sources.sha1, data_sources.sha256 FROM "
1342 +
" LEFT JOIN cases ON "
1344 +
".case_id=cases.id"
1345 +
" LEFT JOIN organizations ON cases.org_id=organizations.id"
1346 +
" LEFT JOIN data_sources ON "
1348 +
".data_source_id=data_sources.id"
1349 +
" WHERE value IN (";
1350 StringBuilder inValuesBuilder =
new StringBuilder(sql);
1351 for (String value : values) {
1352 if (value != null) {
1353 inValuesBuilder.append(
"'");
1354 inValuesBuilder.append(CorrelationAttributeNormalizer.normalize(aType, value));
1355 inValuesBuilder.append(
"',");
1358 inValuesBuilder.deleteCharAt(inValuesBuilder.length() - 1);
1359 inValuesBuilder.append(
")");
1360 return inValuesBuilder.toString();
1377 private List<CorrelationAttributeInstance> getArtifactInstances(String sql, CorrelationAttributeInstance.Type aType) throws CorrelationAttributeNormalizationException, CentralRepoException {
1378 Connection conn = connect();
1379 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1380 CorrelationAttributeInstance artifactInstance;
1381 PreparedStatement preparedStatement = null;
1382 ResultSet resultSet = null;
1384 preparedStatement = conn.prepareStatement(sql);
1385 resultSet = preparedStatement.executeQuery();
1386 while (resultSet.next()) {
1387 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1388 artifactInstances.add(artifactInstance);
1390 }
catch (SQLException ex) {
1391 throw new CentralRepoException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
1393 CentralRepoDbUtil.closeStatement(preparedStatement);
1394 CentralRepoDbUtil.closeResultSet(resultSet);
1395 CentralRepoDbUtil.closeConnection(conn);
1397 return artifactInstances;
1411 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1412 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1414 Connection conn = connect();
1416 Long instanceCount = 0L;
1417 PreparedStatement preparedStatement = null;
1418 ResultSet resultSet = null;
1420 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1422 =
"SELECT count(*) FROM "
1427 preparedStatement = conn.prepareStatement(sql);
1428 preparedStatement.setString(1, normalizedValue);
1429 resultSet = preparedStatement.executeQuery();
1431 instanceCount = resultSet.getLong(1);
1432 }
catch (SQLException ex) {
1433 throw new CentralRepoException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1435 CentralRepoDbUtil.closeStatement(preparedStatement);
1436 CentralRepoDbUtil.closeResultSet(resultSet);
1437 CentralRepoDbUtil.closeConnection(conn);
1440 return instanceCount;
1444 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1445 if (corAttr == null) {
1446 throw new CentralRepoException(
"CorrelationAttribute is null");
1448 Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
1449 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1450 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1451 return commonalityPercentage.intValue();
1465 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1466 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1468 Connection conn = connect();
1470 Long instanceCount = 0L;
1471 PreparedStatement preparedStatement = null;
1472 ResultSet resultSet = null;
1474 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1476 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1478 +
" WHERE value=?) AS "
1480 +
"_distinct_case_data_source_tuple";
1483 preparedStatement = conn.prepareStatement(sql);
1484 preparedStatement.setString(1, normalizedValue);
1485 resultSet = preparedStatement.executeQuery();
1487 instanceCount = resultSet.getLong(1);
1488 }
catch (SQLException ex) {
1489 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1491 CentralRepoDbUtil.closeStatement(preparedStatement);
1492 CentralRepoDbUtil.closeResultSet(resultSet);
1493 CentralRepoDbUtil.closeConnection(conn);
1496 return instanceCount;
1500 public Long getCountUniqueDataSources() throws CentralRepoException {
1501 Connection conn = connect();
1503 Long instanceCount = 0L;
1504 PreparedStatement preparedStatement = null;
1505 ResultSet resultSet = null;
1507 String stmt =
"SELECT count(*) FROM data_sources";
1510 preparedStatement = conn.prepareStatement(stmt);
1511 resultSet = preparedStatement.executeQuery();
1513 instanceCount = resultSet.getLong(1);
1514 }
catch (SQLException ex) {
1515 throw new CentralRepoException(
"Error counting data sources.", ex);
1517 CentralRepoDbUtil.closeStatement(preparedStatement);
1518 CentralRepoDbUtil.closeResultSet(resultSet);
1519 CentralRepoDbUtil.closeConnection(conn);
1522 return instanceCount;
1537 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws CentralRepoException {
1538 Connection conn = connect();
1540 Long instanceCount = 0L;
1541 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1542 PreparedStatement preparedStatement = null;
1543 ResultSet resultSet = null;
1546 String sql =
"SELECT 0 ";
1548 for (CorrelationAttributeInstance.Type type : artifactTypes) {
1549 String table_name = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1551 +=
"+ (SELECT count(*) FROM "
1553 +
" WHERE data_source_id=" + correlationDataSource.getID() +
")";
1556 preparedStatement = conn.prepareStatement(sql);
1558 resultSet = preparedStatement.executeQuery();
1560 instanceCount = resultSet.getLong(1);
1561 }
catch (SQLException ex) {
1562 throw new CentralRepoException(
"Error counting artifact instances by caseName/dataSource.", ex);
1564 CentralRepoDbUtil.closeStatement(preparedStatement);
1565 CentralRepoDbUtil.closeResultSet(resultSet);
1566 CentralRepoDbUtil.closeConnection(conn);
1569 return instanceCount;
1580 public void addAttributeInstanceBulk(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1582 if (eamArtifact.getCorrelationType() == null) {
1583 throw new CentralRepoException(
"Correlation type is null");
1586 synchronized (bulkArtifacts) {
1587 if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
1588 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()),
new ArrayList<>());
1590 bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
1591 bulkArtifactsCount++;
1593 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1594 commitAttributeInstancesBulk();
1604 protected abstract String getConflictClause();
1611 public void commitAttributeInstancesBulk() throws CentralRepoException {
1612 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1614 Connection conn = connect();
1615 PreparedStatement bulkPs = null;
1618 synchronized (bulkArtifacts) {
1619 if (bulkArtifactsCount == 0) {
1623 for (String tableName : bulkArtifacts.keySet()) {
1628 +
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1629 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1630 +
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) "
1631 + getConflictClause();
1633 bulkPs = conn.prepareStatement(sql);
1635 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
1636 for (CorrelationAttributeInstance eamArtifact : eamArtifacts) {
1638 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1640 if (eamArtifact.getCorrelationCase() == null) {
1641 throw new CentralRepoException(
"CorrelationAttributeInstance case is null for: "
1642 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1643 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1644 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1646 if (eamArtifact.getCorrelationDataSource() == null) {
1647 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null for: "
1648 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1649 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1650 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1652 if (eamArtifact.getKnownStatus() == null) {
1653 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null for: "
1654 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1655 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1656 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue()
1657 +
"\n\tEam Instance: "
1658 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1659 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID());
1662 if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) {
1663 bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
1664 bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID());
1665 bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
1666 bulkPs.setString(4, eamArtifact.getCorrelationValue());
1667 bulkPs.setString(5, eamArtifact.getFilePath());
1668 bulkPs.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
1669 if (
"".equals(eamArtifact.getComment())) {
1670 bulkPs.setNull(7, Types.INTEGER);
1672 bulkPs.setString(7, eamArtifact.getComment());
1674 bulkPs.setLong(8, eamArtifact.getFileObjectId());
1677 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1678 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1679 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1680 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue())
1681 +
"\n\tEam Instance: "
1682 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1683 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID()
1684 +
"\n\t\tFilePath: " + eamArtifact.getFilePath());
1690 bulkPs.executeBatch();
1691 bulkArtifacts.get(tableName).clear();
1694 TimingMetric timingMetric = HealthMonitor.getTimingMetric(
"Central Repository: Bulk insert");
1695 HealthMonitor.submitTimingMetric(timingMetric);
1698 bulkArtifactsCount = 0;
1700 }
catch (SQLException ex) {
1701 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
1703 CentralRepoDbUtil.closeStatement(bulkPs);
1704 CentralRepoDbUtil.closeConnection(conn);
1712 public void bulkInsertCases(List<CorrelationCase> cases)
throws CentralRepoException {
1713 if (cases == null) {
1714 throw new CentralRepoException(
"cases argument is null");
1717 if (cases.isEmpty()) {
1721 Connection conn = connect();
1724 PreparedStatement bulkPs = null;
1726 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1727 +
"examiner_name, examiner_email, examiner_phone, notes) "
1728 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1729 + getConflictClause();
1730 bulkPs = conn.prepareStatement(sql);
1732 for (CorrelationCase eamCase : cases) {
1733 bulkPs.setString(1, eamCase.getCaseUUID());
1734 if (null == eamCase.getOrg()) {
1735 bulkPs.setNull(2, Types.INTEGER);
1737 bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1739 bulkPs.setString(3, eamCase.getDisplayName());
1740 bulkPs.setString(4, eamCase.getCreationDate());
1742 if (
"".equals(eamCase.getCaseNumber())) {
1743 bulkPs.setNull(5, Types.INTEGER);
1745 bulkPs.setString(5, eamCase.getCaseNumber());
1747 if (
"".equals(eamCase.getExaminerName())) {
1748 bulkPs.setNull(6, Types.INTEGER);
1750 bulkPs.setString(6, eamCase.getExaminerName());
1752 if (
"".equals(eamCase.getExaminerEmail())) {
1753 bulkPs.setNull(7, Types.INTEGER);
1755 bulkPs.setString(7, eamCase.getExaminerEmail());
1757 if (
"".equals(eamCase.getExaminerPhone())) {
1758 bulkPs.setNull(8, Types.INTEGER);
1760 bulkPs.setString(8, eamCase.getExaminerPhone());
1762 if (
"".equals(eamCase.getNotes())) {
1763 bulkPs.setNull(9, Types.INTEGER);
1765 bulkPs.setString(9, eamCase.getNotes());
1773 if (counter >= bulkArtifactsThreshold) {
1774 bulkPs.executeBatch();
1779 bulkPs.executeBatch();
1780 }
catch (SQLException ex) {
1781 throw new CentralRepoException(
"Error inserting bulk cases.", ex);
1783 CentralRepoDbUtil.closeStatement(bulkPs);
1784 CentralRepoDbUtil.closeConnection(conn);
1798 public void updateAttributeInstanceComment(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1800 if (eamArtifact == null) {
1801 throw new CentralRepoException(
"CorrelationAttributeInstance is null");
1803 if (eamArtifact.getCorrelationCase() == null) {
1804 throw new CentralRepoException(
"Correlation case is null");
1806 if (eamArtifact.getCorrelationDataSource() == null) {
1807 throw new CentralRepoException(
"Correlation data source is null");
1809 Connection conn = connect();
1810 PreparedStatement preparedQuery = null;
1811 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1816 +
"WHERE case_id=? "
1817 +
"AND data_source_id=? "
1819 +
"AND file_path=?";
1822 preparedQuery = conn.prepareStatement(sqlUpdate);
1823 preparedQuery.setString(1, eamArtifact.getComment());
1824 preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID());
1825 preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID());
1826 preparedQuery.setString(4, eamArtifact.getCorrelationValue());
1827 preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
1828 preparedQuery.executeUpdate();
1829 }
catch (SQLException ex) {
1830 throw new CentralRepoException(
"Error getting/setting artifact instance comment=" + eamArtifact.getComment(), ex);
1832 CentralRepoDbUtil.closeStatement(preparedQuery);
1833 CentralRepoDbUtil.closeConnection(conn);
1852 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1853 CorrelationDataSource correlationDataSource,
long objectID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1855 if (correlationCase == null) {
1856 throw new CentralRepoException(
"Correlation case is null");
1859 Connection conn = connect();
1861 PreparedStatement preparedStatement = null;
1862 ResultSet resultSet = null;
1863 CorrelationAttributeInstance correlationAttributeInstance = null;
1867 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1869 =
"SELECT id, value, file_path, known_status, comment FROM "
1871 +
" WHERE case_id=?"
1872 +
" AND file_obj_id=?";
1874 preparedStatement = conn.prepareStatement(sql);
1875 preparedStatement.setInt(1, correlationCase.getID());
1876 preparedStatement.setInt(2, (
int) objectID);
1877 resultSet = preparedStatement.executeQuery();
1878 if (resultSet.next()) {
1879 int instanceId = resultSet.getInt(1);
1880 String value = resultSet.getString(2);
1881 String filePath = resultSet.getString(3);
1882 int knownStatus = resultSet.getInt(4);
1883 String comment = resultSet.getString(5);
1885 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1886 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
1888 }
catch (SQLException ex) {
1889 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1891 CentralRepoDbUtil.closeStatement(preparedStatement);
1892 CentralRepoDbUtil.closeResultSet(resultSet);
1893 CentralRepoDbUtil.closeConnection(conn);
1896 return correlationAttributeInstance;
1914 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1915 CorrelationDataSource correlationDataSource, String value, String filePath)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1917 if (correlationCase == null) {
1918 throw new CentralRepoException(
"Correlation case is null");
1920 if (correlationDataSource == null) {
1921 throw new CentralRepoException(
"Correlation data source is null");
1923 if (filePath == null) {
1924 throw new CentralRepoException(
"Correlation file path is null");
1927 Connection conn = connect();
1929 PreparedStatement preparedStatement = null;
1930 ResultSet resultSet = null;
1931 CorrelationAttributeInstance correlationAttributeInstance = null;
1934 String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
1936 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1938 =
"SELECT id, known_status, comment FROM "
1940 +
" WHERE case_id=?"
1941 +
" AND data_source_id=?"
1943 +
" AND file_path=?";
1945 preparedStatement = conn.prepareStatement(sql);
1946 preparedStatement.setInt(1, correlationCase.getID());
1947 preparedStatement.setInt(2, correlationDataSource.getID());
1948 preparedStatement.setString(3, normalizedValue);
1949 preparedStatement.setString(4, filePath.toLowerCase());
1950 resultSet = preparedStatement.executeQuery();
1951 if (resultSet.next()) {
1952 int instanceId = resultSet.getInt(1);
1953 int knownStatus = resultSet.getInt(2);
1954 String comment = resultSet.getString(3);
1956 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1957 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
1959 }
catch (SQLException ex) {
1960 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1962 CentralRepoDbUtil.closeStatement(preparedStatement);
1963 CentralRepoDbUtil.closeResultSet(resultSet);
1964 CentralRepoDbUtil.closeConnection(conn);
1967 return correlationAttributeInstance;
1981 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws CentralRepoException {
1982 if (eamArtifact == null) {
1983 throw new CentralRepoException(
"CorrelationAttribute is null");
1985 if (knownStatus == null) {
1986 throw new CentralRepoException(
"Known status is null");
1989 if (eamArtifact.getCorrelationCase() == null) {
1990 throw new CentralRepoException(
"Correlation case is null");
1992 if (eamArtifact.getCorrelationDataSource() == null) {
1993 throw new CentralRepoException(
"Correlation data source is null");
1996 Connection conn = connect();
1998 PreparedStatement preparedUpdate = null;
1999 PreparedStatement preparedQuery = null;
2000 ResultSet resultSet = null;
2002 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
2007 +
" WHERE case_id=? "
2008 +
"AND data_source_id=? "
2010 +
"AND file_path=?";
2015 +
" SET known_status=? WHERE id=?";
2018 preparedQuery = conn.prepareStatement(sqlQuery);
2019 preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID());
2020 preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID());
2021 preparedQuery.setString(3, eamArtifact.getCorrelationValue());
2022 preparedQuery.setString(4, eamArtifact.getFilePath());
2023 resultSet = preparedQuery.executeQuery();
2024 if (resultSet.next()) {
2025 int instance_id = resultSet.getInt(
"id");
2026 preparedUpdate = conn.prepareStatement(sqlUpdate);
2028 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
2029 preparedUpdate.setInt(2, instance_id);
2031 preparedUpdate.executeUpdate();
2038 CorrelationCase correlationCaseWithId = getCaseByUUID(eamArtifact.getCorrelationCase().getCaseUUID());
2039 if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) {
2040 newDataSource(eamArtifact.getCorrelationDataSource());
2042 eamArtifact.setKnownStatus(knownStatus);
2043 addArtifactInstance(eamArtifact);
2046 }
catch (SQLException ex) {
2047 throw new CentralRepoException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
2049 CentralRepoDbUtil.closeStatement(preparedUpdate);
2050 CentralRepoDbUtil.closeStatement(preparedQuery);
2051 CentralRepoDbUtil.closeResultSet(resultSet);
2052 CentralRepoDbUtil.closeConnection(conn);
2065 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2067 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2069 Connection conn = connect();
2071 Long badInstances = 0L;
2072 PreparedStatement preparedStatement = null;
2073 ResultSet resultSet = null;
2075 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2077 =
"SELECT count(*) FROM "
2079 +
" WHERE value=? AND known_status=?";
2082 preparedStatement = conn.prepareStatement(sql);
2083 preparedStatement.setString(1, normalizedValue);
2084 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2085 resultSet = preparedStatement.executeQuery();
2087 badInstances = resultSet.getLong(1);
2088 }
catch (SQLException ex) {
2089 throw new CentralRepoException(
"Error getting count of notable artifact instances.", ex);
2091 CentralRepoDbUtil.closeStatement(preparedStatement);
2092 CentralRepoDbUtil.closeResultSet(resultSet);
2093 CentralRepoDbUtil.closeConnection(conn);
2096 return badInstances;
2112 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2114 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2116 Connection conn = connect();
2118 Collection<String> caseNames =
new LinkedHashSet<>();
2120 PreparedStatement preparedStatement = null;
2121 ResultSet resultSet = null;
2123 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2125 =
"SELECT DISTINCT case_name FROM "
2127 +
" INNER JOIN cases ON "
2129 +
".case_id=cases.id WHERE "
2133 +
".known_status=?";
2136 preparedStatement = conn.prepareStatement(sql);
2137 preparedStatement.setString(1, normalizedValue);
2138 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2139 resultSet = preparedStatement.executeQuery();
2140 while (resultSet.next()) {
2141 caseNames.add(resultSet.getString(
"case_name"));
2143 }
catch (SQLException ex) {
2144 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2146 CentralRepoDbUtil.closeStatement(preparedStatement);
2147 CentralRepoDbUtil.closeResultSet(resultSet);
2148 CentralRepoDbUtil.closeConnection(conn);
2151 return caseNames.stream().collect(Collectors.toList());
2167 public List<String> getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2169 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2171 Connection conn = connect();
2173 Collection<String> caseNames =
new LinkedHashSet<>();
2175 PreparedStatement preparedStatement = null;
2176 ResultSet resultSet = null;
2178 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2180 =
"SELECT DISTINCT case_name FROM "
2182 +
" INNER JOIN cases ON "
2184 +
".case_id=cases.id WHERE "
2189 preparedStatement = conn.prepareStatement(sql);
2190 preparedStatement.setString(1, normalizedValue);
2191 resultSet = preparedStatement.executeQuery();
2192 while (resultSet.next()) {
2193 caseNames.add(resultSet.getString(
"case_name"));
2195 }
catch (SQLException ex) {
2196 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2198 CentralRepoDbUtil.closeStatement(preparedStatement);
2199 CentralRepoDbUtil.closeResultSet(resultSet);
2200 CentralRepoDbUtil.closeConnection(conn);
2203 return caseNames.stream().collect(Collectors.toList());
2214 public void deleteReferenceSet(
int referenceSetID)
throws CentralRepoException {
2215 deleteReferenceSetEntries(referenceSetID);
2216 deleteReferenceSetEntry(referenceSetID);
2226 private void deleteReferenceSetEntry(
int referenceSetID)
throws CentralRepoException {
2227 Connection conn = connect();
2229 PreparedStatement preparedStatement = null;
2230 String sql =
"DELETE FROM reference_sets WHERE id=?";
2233 preparedStatement = conn.prepareStatement(sql);
2234 preparedStatement.setInt(1, referenceSetID);
2235 preparedStatement.executeUpdate();
2236 }
catch (SQLException ex) {
2237 throw new CentralRepoException(
"Error deleting reference set " + referenceSetID, ex);
2239 CentralRepoDbUtil.closeStatement(preparedStatement);
2240 CentralRepoDbUtil.closeConnection(conn);
2252 private void deleteReferenceSetEntries(
int referenceSetID)
throws CentralRepoException {
2253 Connection conn = connect();
2255 PreparedStatement preparedStatement = null;
2256 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2259 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
2262 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2263 preparedStatement.setInt(1, referenceSetID);
2264 preparedStatement.executeUpdate();
2265 }
catch (SQLException ex) {
2266 throw new CentralRepoException(
"Error deleting files from reference set " + referenceSetID, ex);
2268 CentralRepoDbUtil.closeStatement(preparedStatement);
2269 CentralRepoDbUtil.closeConnection(conn);
2287 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws CentralRepoException {
2288 CentralRepoFileSet refSet = this.getReferenceSetByID(referenceSetID);
2289 if (refSet == null) {
2293 return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
2308 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2309 return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
2313 public HashHitInfo lookupHash(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2314 int correlationTypeID = CorrelationAttributeInstance.FILES_TYPE_ID;
2315 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), hash);
2317 Connection conn = connect();
2319 PreparedStatement preparedStatement = null;
2320 ResultSet resultSet = null;
2321 String sql =
"SELECT value,comment FROM %s WHERE value=? AND reference_set_id=?";
2323 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2326 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2327 preparedStatement.setString(1, normalizeValued);
2328 preparedStatement.setInt(2, referenceSetID);
2329 resultSet = preparedStatement.executeQuery();
2330 if (resultSet.next()) {
2331 String comment = resultSet.getString(
"comment");
2332 String hashFound = resultSet.getString(
"value");
2333 HashHitInfo found =
new HashHitInfo(hashFound,
"",
"");
2334 found.addComment(comment);
2339 }
catch (SQLException ex) {
2340 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2342 CentralRepoDbUtil.closeStatement(preparedStatement);
2343 CentralRepoDbUtil.closeResultSet(resultSet);
2344 CentralRepoDbUtil.closeConnection(conn);
2358 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2360 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
2362 Connection conn = connect();
2364 Long matchingInstances = 0L;
2365 PreparedStatement preparedStatement = null;
2366 ResultSet resultSet = null;
2367 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2369 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2372 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2373 preparedStatement.setString(1, normalizeValued);
2374 preparedStatement.setInt(2, referenceSetID);
2375 resultSet = preparedStatement.executeQuery();
2377 matchingInstances = resultSet.getLong(1);
2378 }
catch (SQLException ex) {
2379 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2381 CentralRepoDbUtil.closeStatement(preparedStatement);
2382 CentralRepoDbUtil.closeResultSet(resultSet);
2383 CentralRepoDbUtil.closeConnection(conn);
2386 return 0 < matchingInstances;
2398 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2401 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
2404 if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
2408 Connection conn = connect();
2410 Long badInstances = 0L;
2411 PreparedStatement preparedStatement = null;
2412 ResultSet resultSet = null;
2413 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2416 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2417 preparedStatement.setString(1, normalizeValued);
2418 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2419 resultSet = preparedStatement.executeQuery();
2421 badInstances = resultSet.getLong(1);
2422 }
catch (SQLException ex) {
2423 throw new CentralRepoException(
"Error determining if artifact is notable by reference.", ex);
2425 CentralRepoDbUtil.closeStatement(preparedStatement);
2426 CentralRepoDbUtil.closeResultSet(resultSet);
2427 CentralRepoDbUtil.closeConnection(conn);
2430 return 0 < badInstances;
2442 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2444 throw new CentralRepoException(
"Correlation type is null");
2447 if (instanceTableCallback == null) {
2448 throw new CentralRepoException(
"Callback interface is null");
2451 Connection conn = connect();
2452 PreparedStatement preparedStatement = null;
2453 ResultSet resultSet = null;
2454 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2455 StringBuilder sql =
new StringBuilder();
2456 sql.append(
"select * from ");
2457 sql.append(tableName);
2460 preparedStatement = conn.prepareStatement(sql.toString());
2461 resultSet = preparedStatement.executeQuery();
2462 instanceTableCallback.process(resultSet);
2463 }
catch (SQLException ex) {
2464 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2466 CentralRepoDbUtil.closeStatement(preparedStatement);
2467 CentralRepoDbUtil.closeResultSet(resultSet);
2468 CentralRepoDbUtil.closeConnection(conn);
2482 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2484 throw new CentralRepoException(
"Correlation type is null");
2487 if (instanceTableCallback == null) {
2488 throw new CentralRepoException(
"Callback interface is null");
2491 if (whereClause == null) {
2492 throw new CentralRepoException(
"Where clause is null");
2495 Connection conn = connect();
2496 PreparedStatement preparedStatement = null;
2497 ResultSet resultSet = null;
2498 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2499 StringBuilder sql =
new StringBuilder(300);
2500 sql.append(
"select * from ")
2503 .append(whereClause);
2506 preparedStatement = conn.prepareStatement(sql.toString());
2507 resultSet = preparedStatement.executeQuery();
2508 instanceTableCallback.process(resultSet);
2509 }
catch (SQLException ex) {
2510 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2512 CentralRepoDbUtil.closeStatement(preparedStatement);
2513 CentralRepoDbUtil.closeResultSet(resultSet);
2514 CentralRepoDbUtil.closeConnection(conn);
2527 public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2529 if (instanceTableCallback == null) {
2530 throw new CentralRepoException(
"Callback interface is null");
2533 if (selectClause == null) {
2534 throw new CentralRepoException(
"Select clause is null");
2537 Connection conn = connect();
2538 PreparedStatement preparedStatement = null;
2539 ResultSet resultSet = null;
2540 StringBuilder sql =
new StringBuilder(300);
2541 sql.append(
"select ")
2542 .append(selectClause);
2545 preparedStatement = conn.prepareStatement(sql.toString());
2546 resultSet = preparedStatement.executeQuery();
2547 instanceTableCallback.process(resultSet);
2548 }
catch (SQLException ex) {
2549 throw new CentralRepoException(
"Error running query", ex);
2551 CentralRepoDbUtil.closeStatement(preparedStatement);
2552 CentralRepoDbUtil.closeResultSet(resultSet);
2553 CentralRepoDbUtil.closeConnection(conn);
2558 public void executeCommand(String sql, List<Object> params)
throws CentralRepoException {
2560 try (Connection conn = connect();) {
2562 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2565 if (params != null) {
2567 for (Object param : params) {
2568 preparedStatement.setObject(paramIndex, param);
2573 preparedStatement.executeUpdate();
2574 }
catch (SQLException ex) {
2575 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL %s", sql), ex);
2580 public void executeQuery(String sql, List<Object> params, CentralRepositoryDbQueryCallback queryCallback)
throws CentralRepoException {
2581 if (queryCallback == null) {
2582 throw new CentralRepoException(
"Query callback is null");
2586 try ( Connection conn = connect();) {
2587 PreparedStatement preparedStatement = conn.prepareStatement(sql);
2590 if (params != null) {
2592 for (Object param : params) {
2593 preparedStatement.setObject(paramIndex, param);
2598 try (ResultSet resultSet = preparedStatement.executeQuery();) {
2599 queryCallback.process(resultSet);
2601 }
catch (SQLException ex) {
2602 throw new CentralRepoException(String.format(
"Error executing prepared statement for SQL query %s", sql), ex);
2607 public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg)
throws CentralRepoException {
2608 if (eamOrg == null) {
2609 throw new CentralRepoException(
"EamOrganization is null");
2610 }
else if (eamOrg.getOrgID() != -1) {
2611 throw new CentralRepoException(
"EamOrganization already has an ID");
2614 Connection conn = connect();
2615 ResultSet generatedKeys = null;
2616 PreparedStatement preparedStatement = null;
2617 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2618 + getConflictClause();
2621 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2622 preparedStatement.setString(1, eamOrg.getName());
2623 preparedStatement.setString(2, eamOrg.getPocName());
2624 preparedStatement.setString(3, eamOrg.getPocEmail());
2625 preparedStatement.setString(4, eamOrg.getPocPhone());
2627 preparedStatement.executeUpdate();
2628 generatedKeys = preparedStatement.getGeneratedKeys();
2629 if (generatedKeys.next()) {
2630 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2633 throw new SQLException(
"Creating user failed, no ID obtained.");
2635 }
catch (SQLException ex) {
2636 throw new CentralRepoException(
"Error inserting new organization.", ex);
2638 CentralRepoDbUtil.closeStatement(preparedStatement);
2639 CentralRepoDbUtil.closeResultSet(generatedKeys);
2640 CentralRepoDbUtil.closeConnection(conn);
2652 public List<CentralRepoOrganization> getOrganizations() throws CentralRepoException {
2653 Connection conn = connect();
2655 List<CentralRepoOrganization> orgs =
new ArrayList<>();
2656 PreparedStatement preparedStatement = null;
2657 ResultSet resultSet = null;
2658 String sql =
"SELECT * FROM organizations";
2661 preparedStatement = conn.prepareStatement(sql);
2662 resultSet = preparedStatement.executeQuery();
2663 while (resultSet.next()) {
2664 orgs.add(getEamOrganizationFromResultSet(resultSet));
2668 }
catch (SQLException ex) {
2669 throw new CentralRepoException(
"Error getting all organizations.", ex);
2671 CentralRepoDbUtil.closeStatement(preparedStatement);
2672 CentralRepoDbUtil.closeResultSet(resultSet);
2673 CentralRepoDbUtil.closeConnection(conn);
2687 public CentralRepoOrganization getOrganizationByID(
int orgID)
throws CentralRepoException {
2688 Connection conn = connect();
2690 PreparedStatement preparedStatement = null;
2691 ResultSet resultSet = null;
2692 String sql =
"SELECT * FROM organizations WHERE id=?";
2695 preparedStatement = conn.prepareStatement(sql);
2696 preparedStatement.setInt(1, orgID);
2697 resultSet = preparedStatement.executeQuery();
2699 return getEamOrganizationFromResultSet(resultSet);
2701 }
catch (SQLException ex) {
2702 throw new CentralRepoException(
"Error getting organization by id.", ex);
2704 CentralRepoDbUtil.closeStatement(preparedStatement);
2705 CentralRepoDbUtil.closeResultSet(resultSet);
2706 CentralRepoDbUtil.closeConnection(conn);
2720 public CentralRepoOrganization getReferenceSetOrganization(
int referenceSetID)
throws CentralRepoException {
2722 CentralRepoFileSet globalSet = getReferenceSetByID(referenceSetID);
2723 if (globalSet == null) {
2724 throw new CentralRepoException(
"Reference set with ID " + referenceSetID +
" not found");
2726 return (getOrganizationByID(globalSet.getOrgID()));
2736 private void testArgument(CentralRepoOrganization
org)
throws CentralRepoException {
2738 throw new CentralRepoException(
"EamOrganization is null");
2739 }
else if (
org.getOrgID() == -1) {
2740 throw new CentralRepoException(
"Organization has -1 row ID");
2756 public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName)
throws CentralRepoException {
2758 String querySQL =
"SELECT * FROM examiners WHERE login_name = '" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"'";
2759 try (Connection connection = connect();
2760 Statement statement = connection.createStatement();
2761 ResultSet resultSet = statement.executeQuery(querySQL);) {
2763 if (resultSet.next()) {
2764 return new CentralRepoExaminer(resultSet.getLong(
"id"), resultSet.getString(
"login_name"));
2769 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
2771 insertSQL =
"INSERT INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')" + getConflictClause();
2774 insertSQL =
"INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')";
2777 throw new CentralRepoException(String.format(
"Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
2779 statement.execute(insertSQL);
2782 try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
2783 if (resultSet2.next()) {
2784 return new CentralRepoExaminer(resultSet2.getLong(
"id"), resultSet2.getString(
"login_name"));
2786 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName);
2790 }
catch (SQLException ex) {
2791 throw new CentralRepoException(
"Error inserting row in examiners", ex);
2795 }
catch (SQLException ex) {
2796 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName, ex);
2809 public void updateOrganization(CentralRepoOrganization updatedOrganization)
throws CentralRepoException {
2810 testArgument(updatedOrganization);
2812 Connection conn = connect();
2813 PreparedStatement preparedStatement = null;
2814 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2816 preparedStatement = conn.prepareStatement(sql);
2817 preparedStatement.setString(1, updatedOrganization.getName());
2818 preparedStatement.setString(2, updatedOrganization.getPocName());
2819 preparedStatement.setString(3, updatedOrganization.getPocEmail());
2820 preparedStatement.setString(4, updatedOrganization.getPocPhone());
2821 preparedStatement.setInt(5, updatedOrganization.getOrgID());
2822 preparedStatement.executeUpdate();
2823 }
catch (SQLException ex) {
2824 throw new CentralRepoException(
"Error updating organization.", ex);
2826 CentralRepoDbUtil.closeStatement(preparedStatement);
2827 CentralRepoDbUtil.closeConnection(conn);
2832 public void deleteOrganization(CentralRepoOrganization organizationToDelete)
throws CentralRepoException {
2833 testArgument(organizationToDelete);
2835 Connection conn = connect();
2836 PreparedStatement checkIfUsedStatement = null;
2837 ResultSet resultSet = null;
2838 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2839 PreparedStatement deleteOrgStatement = null;
2840 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2842 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2843 checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
2844 checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
2845 resultSet = checkIfUsedStatement.executeQuery();
2847 if (resultSet.getLong(1) > 0) {
2848 throw new CentralRepoException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2850 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2851 deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
2852 deleteOrgStatement.executeUpdate();
2853 }
catch (SQLException ex) {
2854 throw new CentralRepoException(
"Error executing query when attempting to delete organization by id.", ex);
2856 CentralRepoDbUtil.closeStatement(checkIfUsedStatement);
2857 CentralRepoDbUtil.closeStatement(deleteOrgStatement);
2858 CentralRepoDbUtil.closeResultSet(resultSet);
2859 CentralRepoDbUtil.closeConnection(conn);
2873 public int newReferenceSet(CentralRepoFileSet eamGlobalSet)
throws CentralRepoException {
2874 if (eamGlobalSet == null) {
2875 throw new CentralRepoException(
"EamGlobalSet is null");
2878 if (eamGlobalSet.getFileKnownStatus() == null) {
2879 throw new CentralRepoException(
"File known status on the EamGlobalSet is null");
2882 if (eamGlobalSet.getType() == null) {
2883 throw new CentralRepoException(
"Type on the EamGlobalSet is null");
2886 Connection conn = connect();
2888 PreparedStatement preparedStatement1 = null;
2889 PreparedStatement preparedStatement2 = null;
2890 ResultSet resultSet = null;
2891 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2892 + getConflictClause();
2893 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2896 preparedStatement1 = conn.prepareStatement(sql1);
2897 preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
2898 preparedStatement1.setString(2, eamGlobalSet.getSetName());
2899 preparedStatement1.setString(3, eamGlobalSet.getVersion());
2900 preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
2901 preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
2902 preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
2903 preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
2905 preparedStatement1.executeUpdate();
2907 preparedStatement2 = conn.prepareStatement(sql2);
2908 preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
2909 preparedStatement2.setString(2, eamGlobalSet.getSetName());
2910 preparedStatement2.setString(3, eamGlobalSet.getVersion());
2911 preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
2913 resultSet = preparedStatement2.executeQuery();
2915 return resultSet.getInt(
"id");
2917 }
catch (SQLException ex) {
2918 throw new CentralRepoException(
"Error inserting new global set.", ex);
2920 CentralRepoDbUtil.closeStatement(preparedStatement1);
2921 CentralRepoDbUtil.closeStatement(preparedStatement2);
2922 CentralRepoDbUtil.closeResultSet(resultSet);
2923 CentralRepoDbUtil.closeConnection(conn);
2937 public CentralRepoFileSet getReferenceSetByID(
int referenceSetID)
throws CentralRepoException {
2938 Connection conn = connect();
2940 PreparedStatement preparedStatement1 = null;
2941 ResultSet resultSet = null;
2942 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2945 preparedStatement1 = conn.prepareStatement(sql1);
2946 preparedStatement1.setInt(1, referenceSetID);
2947 resultSet = preparedStatement1.executeQuery();
2948 if (resultSet.next()) {
2949 return getEamGlobalSetFromResultSet(resultSet);
2954 }
catch (SQLException ex) {
2955 throw new CentralRepoException(
"Error getting reference set by id.", ex);
2957 CentralRepoDbUtil.closeStatement(preparedStatement1);
2958 CentralRepoDbUtil.closeResultSet(resultSet);
2959 CentralRepoDbUtil.closeConnection(conn);
2973 public List<CentralRepoFileSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
2975 if (correlationType == null) {
2976 throw new CentralRepoException(
"Correlation type is null");
2979 List<CentralRepoFileSet> results =
new ArrayList<>();
2980 Connection conn = connect();
2982 PreparedStatement preparedStatement1 = null;
2983 ResultSet resultSet = null;
2984 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
2987 preparedStatement1 = conn.prepareStatement(sql1);
2988 resultSet = preparedStatement1.executeQuery();
2989 while (resultSet.next()) {
2990 results.add(getEamGlobalSetFromResultSet(resultSet));
2993 }
catch (SQLException ex) {
2994 throw new CentralRepoException(
"Error getting reference sets.", ex);
2996 CentralRepoDbUtil.closeStatement(preparedStatement1);
2997 CentralRepoDbUtil.closeResultSet(resultSet);
2998 CentralRepoDbUtil.closeConnection(conn);
3013 public void addReferenceInstance(CentralRepoFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3014 if (eamGlobalFileInstance.getKnownStatus() == null) {
3015 throw new CentralRepoException(
"Known status of EamGlobalFileInstance is null");
3017 if (correlationType == null) {
3018 throw new CentralRepoException(
"Correlation type is null");
3021 Connection conn = connect();
3023 PreparedStatement preparedStatement = null;
3025 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3026 + getConflictClause();
3029 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(correlationType)));
3030 preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
3031 preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
3032 preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
3033 preparedStatement.setString(4, eamGlobalFileInstance.getComment());
3034 preparedStatement.executeUpdate();
3035 }
catch (SQLException ex) {
3036 throw new CentralRepoException(
"Error inserting new reference instance into reference_ table.", ex);
3038 CentralRepoDbUtil.closeStatement(preparedStatement);
3039 CentralRepoDbUtil.closeConnection(conn);
3056 public boolean referenceSetExists(String referenceSetName, String version)
throws CentralRepoException {
3057 Connection conn = connect();
3059 PreparedStatement preparedStatement1 = null;
3060 ResultSet resultSet = null;
3061 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
3064 preparedStatement1 = conn.prepareStatement(sql1);
3065 preparedStatement1.setString(1, referenceSetName);
3066 preparedStatement1.setString(2, version);
3067 resultSet = preparedStatement1.executeQuery();
3068 return (resultSet.next());
3070 }
catch (SQLException ex) {
3071 throw new CentralRepoException(
"Error testing whether reference set exists (name: " + referenceSetName
3072 +
" version: " + version, ex);
3074 CentralRepoDbUtil.closeStatement(preparedStatement1);
3075 CentralRepoDbUtil.closeResultSet(resultSet);
3076 CentralRepoDbUtil.closeConnection(conn);
3086 public void bulkInsertReferenceTypeEntries(Set<CentralRepoFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws CentralRepoException {
3087 if (contentType == null) {
3088 throw new CentralRepoException(
"Correlation type is null");
3090 if (globalInstances == null) {
3091 throw new CentralRepoException(
"Null set of EamGlobalFileInstance");
3094 Connection conn = connect();
3096 PreparedStatement bulkPs = null;
3098 conn.setAutoCommit(
false);
3101 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3102 + getConflictClause();
3104 bulkPs = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(contentType)));
3106 for (CentralRepoFileInstance globalInstance : globalInstances) {
3107 if (globalInstance.getKnownStatus() == null) {
3108 throw new CentralRepoException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
3111 bulkPs.setInt(1, globalInstance.getGlobalSetID());
3112 bulkPs.setString(2, globalInstance.getMD5Hash());
3113 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
3114 bulkPs.setString(4, globalInstance.getComment());
3118 bulkPs.executeBatch();
3120 }
catch (SQLException | CentralRepoException ex) {
3123 }
catch (SQLException ex2) {
3126 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
3128 CentralRepoDbUtil.closeStatement(bulkPs);
3129 CentralRepoDbUtil.closeConnection(conn);
3144 public List<CentralRepoFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws CentralRepoException, CorrelationAttributeNormalizationException {
3145 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
3147 Connection conn = connect();
3149 List<CentralRepoFileInstance> globalFileInstances =
new ArrayList<>();
3150 PreparedStatement preparedStatement1 = null;
3151 ResultSet resultSet = null;
3152 String sql1 =
"SELECT * FROM %s WHERE value=?";
3155 preparedStatement1 = conn.prepareStatement(String.format(sql1, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
3156 preparedStatement1.setString(1, normalizeValued);
3157 resultSet = preparedStatement1.executeQuery();
3158 while (resultSet.next()) {
3159 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
3162 }
catch (SQLException ex) {
3163 throw new CentralRepoException(
"Error getting reference instances by type and value.", ex);
3165 CentralRepoDbUtil.closeStatement(preparedStatement1);
3166 CentralRepoDbUtil.closeResultSet(resultSet);
3167 CentralRepoDbUtil.closeConnection(conn);
3170 return globalFileInstances;
3183 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3184 if (newType == null) {
3185 throw new CentralRepoException(
"Correlation type is null");
3188 if (-1 == newType.getId()) {
3189 typeId = newCorrelationTypeNotKnownId(newType);
3191 typeId = newCorrelationTypeKnownId(newType);
3194 synchronized (typeCache) {
3195 typeCache.put(newType.getId(), newType);
3210 public int newCorrelationTypeNotKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3211 Connection conn = connect();
3213 PreparedStatement preparedStatement = null;
3214 PreparedStatement preparedStatementQuery = null;
3215 ResultSet resultSet = null;
3220 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
3222 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3225 preparedStatement = conn.prepareStatement(insertSql);
3227 preparedStatement.setString(1, newType.getDisplayName());
3228 preparedStatement.setString(2, newType.getDbTableName());
3229 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
3230 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
3232 preparedStatement.executeUpdate();
3234 preparedStatementQuery = conn.prepareStatement(querySql);
3235 preparedStatementQuery.setString(1, newType.getDisplayName());
3236 preparedStatementQuery.setString(2, newType.getDbTableName());
3238 resultSet = preparedStatementQuery.executeQuery();
3239 if (resultSet.next()) {
3240 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3241 typeId = correlationType.getId();
3243 }
catch (SQLException ex) {
3244 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3246 CentralRepoDbUtil.closeStatement(preparedStatement);
3247 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3248 CentralRepoDbUtil.closeResultSet(resultSet);
3249 CentralRepoDbUtil.closeConnection(conn);
3263 private int newCorrelationTypeKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3264 Connection conn = connect();
3266 PreparedStatement preparedStatement = null;
3267 PreparedStatement preparedStatementQuery = null;
3268 ResultSet resultSet = null;
3273 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3275 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3278 preparedStatement = conn.prepareStatement(insertSql);
3280 preparedStatement.setInt(1, newType.getId());
3281 preparedStatement.setString(2, newType.getDisplayName());
3282 preparedStatement.setString(3, newType.getDbTableName());
3283 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
3284 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
3286 preparedStatement.executeUpdate();
3288 preparedStatementQuery = conn.prepareStatement(querySql);
3289 preparedStatementQuery.setString(1, newType.getDisplayName());
3290 preparedStatementQuery.setString(2, newType.getDbTableName());
3292 resultSet = preparedStatementQuery.executeQuery();
3293 if (resultSet.next()) {
3294 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3295 typeId = correlationType.getId();
3297 }
catch (SQLException ex) {
3298 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3300 CentralRepoDbUtil.closeStatement(preparedStatement);
3301 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3302 CentralRepoDbUtil.closeResultSet(resultSet);
3303 CentralRepoDbUtil.closeConnection(conn);
3309 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws CentralRepoException {
3311 synchronized (typeCache) {
3312 if (isCRTypeCacheInitialized ==
false) {
3313 getCorrelationTypesFromCr();
3315 return new ArrayList<>(typeCache.asMap().values());
3329 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws CentralRepoException {
3330 Connection conn = connect();
3332 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3333 PreparedStatement preparedStatement = null;
3334 ResultSet resultSet = null;
3335 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3338 preparedStatement = conn.prepareStatement(sql);
3339 resultSet = preparedStatement.executeQuery();
3340 while (resultSet.next()) {
3341 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3345 }
catch (SQLException ex) {
3346 throw new CentralRepoException(
"Error getting enabled correlation types.", ex);
3348 CentralRepoDbUtil.closeStatement(preparedStatement);
3349 CentralRepoDbUtil.closeResultSet(resultSet);
3350 CentralRepoDbUtil.closeConnection(conn);
3364 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws CentralRepoException {
3365 Connection conn = connect();
3367 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3368 PreparedStatement preparedStatement = null;
3369 ResultSet resultSet = null;
3370 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3373 preparedStatement = conn.prepareStatement(sql);
3374 resultSet = preparedStatement.executeQuery();
3375 while (resultSet.next()) {
3376 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3380 }
catch (SQLException ex) {
3381 throw new CentralRepoException(
"Error getting supported correlation types.", ex);
3383 CentralRepoDbUtil.closeStatement(preparedStatement);
3384 CentralRepoDbUtil.closeResultSet(resultSet);
3385 CentralRepoDbUtil.closeConnection(conn);
3397 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws CentralRepoException {
3398 Connection conn = connect();
3400 PreparedStatement preparedStatement = null;
3401 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3404 preparedStatement = conn.prepareStatement(sql);
3405 preparedStatement.setString(1, aType.getDisplayName());
3406 preparedStatement.setString(2, aType.getDbTableName());
3407 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3408 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3409 preparedStatement.setInt(5, aType.getId());
3410 preparedStatement.executeUpdate();
3411 synchronized (typeCache) {
3412 typeCache.put(aType.getId(), aType);
3414 }
catch (SQLException ex) {
3415 throw new CentralRepoException(
"Error updating correlation type.", ex);
3417 CentralRepoDbUtil.closeStatement(preparedStatement);
3418 CentralRepoDbUtil.closeConnection(conn);
3433 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws CentralRepoException {
3435 synchronized (typeCache) {
3436 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3438 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3441 }
catch (ExecutionException ex) {
3442 throw new CentralRepoException(
"Error getting correlation type", ex);
3455 private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(
int typeId)
throws CentralRepoException {
3456 Connection conn = connect();
3458 CorrelationAttributeInstance.Type aType;
3459 PreparedStatement preparedStatement = null;
3460 ResultSet resultSet = null;
3461 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3464 preparedStatement = conn.prepareStatement(sql);
3465 preparedStatement.setInt(1, typeId);
3466 resultSet = preparedStatement.executeQuery();
3467 if (resultSet.next()) {
3468 aType = getCorrelationTypeFromResultSet(resultSet);
3471 throw new CentralRepoException(
"Failed to find entry for correlation type ID = " + typeId);
3474 }
catch (SQLException ex) {
3475 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
3477 CentralRepoDbUtil.closeStatement(preparedStatement);
3478 CentralRepoDbUtil.closeResultSet(resultSet);
3479 CentralRepoDbUtil.closeConnection(conn);
3489 private void getCorrelationTypesFromCr() throws CentralRepoException {
3492 synchronized (typeCache) {
3493 typeCache.invalidateAll();
3494 isCRTypeCacheInitialized =
false;
3497 String sql =
"SELECT * FROM correlation_types";
3498 try (Connection conn = connect();
3499 PreparedStatement preparedStatement = conn.prepareStatement(sql);
3500 ResultSet resultSet = preparedStatement.executeQuery();) {
3502 synchronized (typeCache) {
3503 while (resultSet.next()) {
3504 CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
3505 typeCache.put(aType.getId(), aType);
3507 isCRTypeCacheInitialized =
true;
3509 }
catch (SQLException ex) {
3510 throw new CentralRepoException(
"Error getting correlation types.", ex);
3524 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3525 if (null == resultSet) {
3529 CentralRepoOrganization eamOrg = null;
3531 resultSet.getInt(
"org_id");
3532 if (!resultSet.wasNull()) {
3534 eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3535 resultSet.getString(
"org_name"),
3536 resultSet.getString(
"poc_name"),
3537 resultSet.getString(
"poc_email"),
3538 resultSet.getString(
"poc_phone"));
3541 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3542 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3543 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3548 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3549 if (null == resultSet) {
3553 CorrelationDataSource eamDataSource =
new CorrelationDataSource(
3554 resultSet.getInt(
"case_id"),
3555 resultSet.getInt(
"id"),
3556 resultSet.getString(
"device_id"),
3557 resultSet.getString(
"name"),
3558 resultSet.getLong(
"datasource_obj_id"),
3559 resultSet.getString(
"md5"),
3560 resultSet.getString(
"sha1"),
3561 resultSet.getString(
"sha256")
3564 return eamDataSource;
3567 private CorrelationAttributeInstance.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
throws CentralRepoException, SQLException {
3568 if (null == resultSet) {
3572 CorrelationAttributeInstance.Type eamArtifactType =
new CorrelationAttributeInstance.Type(
3573 resultSet.getInt(
"id"),
3574 resultSet.getString(
"display_name"),
3575 resultSet.getString(
"db_table_name"),
3576 resultSet.getBoolean(
"supported"),
3577 resultSet.getBoolean(
"enabled")
3580 return eamArtifactType;
3593 private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3594 if (null == resultSet) {
3598 CentralRepoOrganization eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3599 resultSet.getString(
"org_name"),
3600 resultSet.getString(
"poc_name"),
3601 resultSet.getString(
"poc_email"),
3602 resultSet.getString(
"poc_phone"));
3604 return new CorrelationAttributeInstance(
3606 resultSet.getString(
"value"),
3607 resultSet.getInt(
"instance_id"),
3608 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3609 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3610 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3611 new CorrelationDataSource(
3612 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3613 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3614 resultSet.getString(
"file_path"),
3615 resultSet.getString(
"comment"),
3616 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3617 resultSet.getLong(
"file_obj_id"));
3620 private CentralRepoOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3621 if (null == resultSet) {
3625 return new CentralRepoOrganization(
3626 resultSet.getInt(
"id"),
3627 resultSet.getString(
"org_name"),
3628 resultSet.getString(
"poc_name"),
3629 resultSet.getString(
"poc_email"),
3630 resultSet.getString(
"poc_phone")
3634 private CentralRepoFileSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException {
3635 if (null == resultSet) {
3639 return new CentralRepoFileSet(
3640 resultSet.getInt(
"id"),
3641 resultSet.getInt(
"org_id"),
3642 resultSet.getString(
"set_name"),
3643 resultSet.getString(
"version"),
3644 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3645 resultSet.getBoolean(
"read_only"),
3646 CentralRepository.getInstance().getCorrelationTypeById(resultSet.getInt(
"type")),
3647 LocalDate.parse(resultSet.getString(
"import_date"))
3651 private CentralRepoFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3652 if (null == resultSet) {
3656 return new CentralRepoFileInstance(
3657 resultSet.getInt(
"id"),
3658 resultSet.getInt(
"reference_set_id"),
3659 resultSet.getString(
"value"),
3660 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3661 resultSet.getString(
"comment")
3665 private String getPlatformSpecificInsertSQL(String sql)
throws CentralRepoException {
3667 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
3669 return "INSERT " + sql +
" ON CONFLICT DO NOTHING";
3671 return "INSERT OR IGNORE " + sql;
3674 throw new CentralRepoException(
"Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform());
3688 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3695 @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.",
3696 "# {0} - minorVersion",
3697 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3698 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3699 "# {0} - majorVersion",
3700 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3701 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3702 "# {0} - platformName",
3703 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3705 public void upgradeSchema() throws CentralRepoException, SQLException, IncompatibleCentralRepoException {
3707 ResultSet resultSet = null;
3708 Statement statement = null;
3709 PreparedStatement preparedStatement = null;
3710 Connection conn = null;
3711 CentralRepoPlatforms selectedPlatform = null;
3714 conn = connect(
false);
3715 conn.setAutoCommit(
false);
3716 statement = conn.createStatement();
3717 selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
3718 int minorVersion = 0;
3719 String minorVersionStr = null;
3720 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"'");
3721 if (resultSet.next()) {
3722 minorVersionStr = resultSet.getString(
"value");
3724 minorVersion = Integer.parseInt(minorVersionStr);
3725 }
catch (NumberFormatException ex) {
3726 throw new CentralRepoException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3729 throw new CentralRepoException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3732 int majorVersion = 0;
3733 String majorVersionStr = null;
3734 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"'");
3735 if (resultSet.next()) {
3736 majorVersionStr = resultSet.getString(
"value");
3738 majorVersion = Integer.parseInt(majorVersionStr);
3739 }
catch (NumberFormatException ex) {
3740 throw new CentralRepoException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3743 throw new CentralRepoException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3754 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3759 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3760 throw new IncompatibleCentralRepoException(Bundle.AbstractSqlEamDb_upgradeSchema_incompatible());
3762 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3763 logger.log(Level.INFO,
"Central Repository is up to date");
3766 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3767 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3774 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3775 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3776 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3777 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3782 CentralRepoDbUtil.insertDefaultOrganization(conn);
3788 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3789 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3791 final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
3792 final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
3793 final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
3794 final String addValueIndexTemplate = RdbmsCentralRepoFactory.getAddValueIndexTemplate();
3795 final String addKnownStatusIndexTemplate = RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate();
3796 final String addObjectIdIndexTemplate = RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate();
3798 final String addAttributeSql;
3800 switch (selectedPlatform) {
3802 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3805 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3808 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3811 final String dataSourcesTableName =
"data_sources";
3812 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3813 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3814 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3816 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3817 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3818 List<String> instaceTablesToAdd =
new ArrayList<>();
3820 final String wirelessNetworksDbTableName =
"wireless_networks";
3821 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3822 final String macAddressDbTableName =
"mac_address";
3823 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3824 final String imeiNumberDbTableName =
"imei_number";
3825 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3826 final String iccidNumberDbTableName =
"iccid_number";
3827 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3828 final String imsiNumberDbTableName =
"imsi_number";
3829 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3832 preparedStatement = conn.prepareStatement(addAttributeSql);
3833 preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID);
3834 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3835 preparedStatement.setString(3, wirelessNetworksDbTableName);
3836 preparedStatement.setInt(4, 1);
3837 preparedStatement.setInt(5, 1);
3838 preparedStatement.execute();
3841 preparedStatement = conn.prepareStatement(addAttributeSql);
3842 preparedStatement.setInt(1, CorrelationAttributeInstance.MAC_TYPE_ID);
3843 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3844 preparedStatement.setString(3, macAddressDbTableName);
3845 preparedStatement.setInt(4, 1);
3846 preparedStatement.setInt(5, 1);
3847 preparedStatement.execute();
3850 preparedStatement = conn.prepareStatement(addAttributeSql);
3851 preparedStatement.setInt(1, CorrelationAttributeInstance.IMEI_TYPE_ID);
3852 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3853 preparedStatement.setString(3, imeiNumberDbTableName);
3854 preparedStatement.setInt(4, 1);
3855 preparedStatement.setInt(5, 1);
3856 preparedStatement.execute();
3859 preparedStatement = conn.prepareStatement(addAttributeSql);
3860 preparedStatement.setInt(1, CorrelationAttributeInstance.IMSI_TYPE_ID);
3861 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3862 preparedStatement.setString(3, imsiNumberDbTableName);
3863 preparedStatement.setInt(4, 1);
3864 preparedStatement.setInt(5, 1);
3865 preparedStatement.execute();
3868 preparedStatement = conn.prepareStatement(addAttributeSql);
3869 preparedStatement.setInt(1, CorrelationAttributeInstance.ICCID_TYPE_ID);
3870 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3871 preparedStatement.setString(3, iccidNumberDbTableName);
3872 preparedStatement.setInt(4, 1);
3873 preparedStatement.setInt(5, 1);
3874 preparedStatement.execute();
3877 for (String tableName : instaceTablesToAdd) {
3878 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3879 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3880 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3881 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3882 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3886 String instance_type_dbname;
3887 final String objectIdColumnName =
"file_obj_id";
3888 for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
3889 instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
3890 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3891 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3893 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3899 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3900 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3902 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3903 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3905 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3906 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3917 String creationMajorVer;
3918 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3919 if (resultSet.next()) {
3920 creationMajorVer = resultSet.getString(
"value");
3922 creationMajorVer =
"0";
3924 String creationMinorVer;
3925 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3926 if (resultSet.next()) {
3927 creationMinorVer = resultSet.getString(
"value");
3929 creationMinorVer =
"0";
3931 statement.execute(
"DROP TABLE db_info");
3932 if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) {
3933 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3935 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3937 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3938 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3939 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3940 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
3945 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
3946 switch (selectedPlatform) {
3948 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
3950 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
3954 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
3955 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
3956 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
3958 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
3959 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
3960 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
3961 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
3962 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
3963 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesNameIndexStatement());
3964 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesObjectIdIndexStatement());
3965 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
3966 statement.execute(
"DROP TABLE old_data_sources");
3969 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3974 (
new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
3977 (
new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);
3980 (
new CentralRepoDbUpgrader15To16()).upgradeSchema(dbSchemaVersion, conn);
3982 updateSchemaVersion(conn);
3984 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
3985 }
catch (SQLException | CentralRepoException ex) {
3990 }
catch (SQLException ex2) {
3991 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
3995 CentralRepoDbUtil.closeResultSet(resultSet);
3996 CentralRepoDbUtil.closeStatement(preparedStatement);
3997 CentralRepoDbUtil.closeStatement(statement);
3998 CentralRepoDbUtil.closeConnection(conn);
CentralRepoAccount getAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)