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;
41 import java.util.concurrent.ExecutionException;
42 import java.util.concurrent.TimeUnit;
43 import java.util.logging.Level;
44 import org.apache.commons.lang.StringUtils;
45 import org.apache.commons.lang3.tuple.Pair;
46 import org.openide.util.NbBundle.Messages;
54 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
64 abstract class RdbmsCentralRepo
implements CentralRepository {
66 private final static Logger logger = Logger.getLogger(RdbmsCentralRepo.class.getName());
67 static final String SCHEMA_MAJOR_VERSION_KEY =
"SCHEMA_VERSION";
68 static final String SCHEMA_MINOR_VERSION_KEY =
"SCHEMA_MINOR_VERSION";
69 static final String CREATION_SCHEMA_MAJOR_VERSION_KEY =
"CREATION_SCHEMA_MAJOR_VERSION";
70 static final String CREATION_SCHEMA_MINOR_VERSION_KEY =
"CREATION_SCHEMA_MINOR_VERSION";
71 static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION =
new CaseDbSchemaVersionNumber(1, 5);
73 protected final List<CorrelationAttributeInstance.Type> defaultCorrelationTypes;
75 private int bulkArtifactsCount;
76 protected int bulkArtifactsThreshold;
77 private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
78 private static final int CASE_CACHE_TIMEOUT = 5;
79 private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
80 private static final int ACCOUNTS_CACHE_TIMEOUT = 5;
81 private static final Cache<String, CentralRepoAccountType> accountTypesCache = CacheBuilder.newBuilder().build();
82 private static final Cache<Pair<CentralRepoAccountType, String>, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder()
83 .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES).
86 private boolean isCRTypeCacheInitialized;
87 private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build();
88 private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
89 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
91 private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
92 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
94 private static final Cache<String, CorrelationDataSource> dataSourceCacheByDsObjectId = CacheBuilder.newBuilder()
95 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
97 private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
98 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
101 static final int MAX_VALUE_LENGTH = 256;
105 static final int DEFAULT_BULK_THRESHHOLD = 1000;
107 private static final int QUERY_STR_MAX_LEN = 1000;
114 protected RdbmsCentralRepo() throws CentralRepoException {
115 isCRTypeCacheInitialized =
false;
116 bulkArtifactsCount = 0;
117 bulkArtifacts =
new HashMap<>();
119 defaultCorrelationTypes = CorrelationAttributeInstance.getDefaultCorrelationTypes();
120 defaultCorrelationTypes.forEach((type) -> {
121 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(type),
new ArrayList<>());
128 protected abstract Connection connect(
boolean foreignKeys)
throws CentralRepoException;
133 protected abstract Connection connect() throws CentralRepoException;
138 protected abstract Connection getEphemeralConnection();
149 public
void newDbInfo(String name, String value) throws CentralRepoException {
150 Connection conn = connect();
152 PreparedStatement preparedStatement = null;
153 String sql =
"INSERT INTO db_info (name, value) VALUES (?, ?) "
154 + getConflictClause();
156 preparedStatement = conn.prepareStatement(sql);
157 preparedStatement.setString(1, name);
158 preparedStatement.setString(2, value);
159 preparedStatement.executeUpdate();
160 }
catch (SQLException ex) {
161 throw new CentralRepoException(
"Error adding new name/value pair to db_info.", ex);
163 CentralRepoDbUtil.closeStatement(preparedStatement);
164 CentralRepoDbUtil.closeConnection(conn);
170 public void addDataSourceObjectId(
int rowId,
long dataSourceObjectId)
throws CentralRepoException {
171 Connection conn = connect();
172 PreparedStatement preparedStatement = null;
173 String sql =
"UPDATE data_sources SET datasource_obj_id=? WHERE id=?";
175 preparedStatement = conn.prepareStatement(sql);
176 preparedStatement.setLong(1, dataSourceObjectId);
177 preparedStatement.setInt(2, rowId);
178 preparedStatement.executeUpdate();
179 }
catch (SQLException ex) {
180 throw new CentralRepoException(
"Error updating data source object id for data_sources row " + rowId, ex);
182 CentralRepoDbUtil.closeStatement(preparedStatement);
183 CentralRepoDbUtil.closeConnection(conn);
197 public String getDbInfo(String name)
throws CentralRepoException {
198 Connection conn = connect();
200 PreparedStatement preparedStatement = null;
201 ResultSet resultSet = null;
203 String sql =
"SELECT value FROM db_info WHERE name=?";
205 preparedStatement = conn.prepareStatement(sql);
206 preparedStatement.setString(1, name);
207 resultSet = preparedStatement.executeQuery();
208 if (resultSet.next()) {
209 value = resultSet.getString(
"value");
211 }
catch (SQLException ex) {
212 throw new CentralRepoException(
"Error getting value for name.", ex);
214 CentralRepoDbUtil.closeStatement(preparedStatement);
215 CentralRepoDbUtil.closeResultSet(resultSet);
216 CentralRepoDbUtil.closeConnection(conn);
225 public final void clearCaches() {
226 synchronized (typeCache) {
227 typeCache.invalidateAll();
228 isCRTypeCacheInitialized =
false;
230 caseCacheByUUID.invalidateAll();
231 caseCacheById.invalidateAll();
232 dataSourceCacheByDsObjectId.invalidateAll();
233 dataSourceCacheById.invalidateAll();
234 accountsCache.invalidateAll();
246 public void updateDbInfo(String name, String value)
throws CentralRepoException {
247 Connection conn = connect();
249 PreparedStatement preparedStatement = null;
250 String sql =
"UPDATE db_info SET value=? WHERE name=?";
252 preparedStatement = conn.prepareStatement(sql);
253 preparedStatement.setString(1, value);
254 preparedStatement.setString(2, name);
255 preparedStatement.executeUpdate();
256 }
catch (SQLException ex) {
257 throw new CentralRepoException(
"Error updating value for name.", ex);
259 CentralRepoDbUtil.closeStatement(preparedStatement);
260 CentralRepoDbUtil.closeConnection(conn);
274 public synchronized CorrelationCase newCase(CorrelationCase eamCase)
throws CentralRepoException {
276 if (eamCase.getCaseUUID() == null) {
277 throw new CentralRepoException(
"Case UUID is null");
281 CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID());
282 if (cRCase != null) {
286 Connection conn = connect();
287 PreparedStatement preparedStatement = null;
289 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
290 +
"examiner_name, examiner_email, examiner_phone, notes) "
291 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
292 + getConflictClause();
293 ResultSet resultSet = null;
295 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
297 preparedStatement.setString(1, eamCase.getCaseUUID());
298 if (null == eamCase.getOrg()) {
299 preparedStatement.setNull(2, Types.INTEGER);
301 preparedStatement.setInt(2, eamCase.getOrg().getOrgID());
303 preparedStatement.setString(3, eamCase.getDisplayName());
304 preparedStatement.setString(4, eamCase.getCreationDate());
305 if (
"".equals(eamCase.getCaseNumber())) {
306 preparedStatement.setNull(5, Types.INTEGER);
308 preparedStatement.setString(5, eamCase.getCaseNumber());
310 if (
"".equals(eamCase.getExaminerName())) {
311 preparedStatement.setNull(6, Types.INTEGER);
313 preparedStatement.setString(6, eamCase.getExaminerName());
315 if (
"".equals(eamCase.getExaminerEmail())) {
316 preparedStatement.setNull(7, Types.INTEGER);
318 preparedStatement.setString(7, eamCase.getExaminerEmail());
320 if (
"".equals(eamCase.getExaminerPhone())) {
321 preparedStatement.setNull(8, Types.INTEGER);
323 preparedStatement.setString(8, eamCase.getExaminerPhone());
325 if (
"".equals(eamCase.getNotes())) {
326 preparedStatement.setNull(9, Types.INTEGER);
328 preparedStatement.setString(9, eamCase.getNotes());
331 preparedStatement.executeUpdate();
333 resultSet = preparedStatement.getGeneratedKeys();
334 if (!resultSet.next()) {
335 throw new CentralRepoException(String.format(
"Failed to INSERT case %s in central repo", eamCase.getCaseUUID()));
337 int caseID = resultSet.getInt(1);
338 CorrelationCase correlationCase =
new CorrelationCase(caseID, eamCase.getCaseUUID(), eamCase.getOrg(),
339 eamCase.getDisplayName(), eamCase.getCreationDate(), eamCase.getCaseNumber(), eamCase.getExaminerName(),
340 eamCase.getExaminerEmail(), eamCase.getExaminerPhone(), eamCase.getNotes());
341 caseCacheByUUID.put(eamCase.getCaseUUID(), correlationCase);
342 caseCacheById.put(caseID, correlationCase);
343 }
catch (SQLException ex) {
344 throw new CentralRepoException(
"Error inserting new case.", ex);
346 CentralRepoDbUtil.closeResultSet(resultSet);
347 CentralRepoDbUtil.closeStatement(preparedStatement);
348 CentralRepoDbUtil.closeConnection(conn);
352 return getCaseByUUID(eamCase.getCaseUUID());
361 public CorrelationCase newCase(Case autopsyCase)
throws CentralRepoException {
362 if (autopsyCase == null) {
363 throw new CentralRepoException(
"Case is null");
366 CorrelationCase curCeCase =
new CorrelationCase(
368 autopsyCase.getName(),
369 CentralRepoOrganization.getDefault(),
370 autopsyCase.getDisplayName(),
371 autopsyCase.getCreatedDate(),
372 autopsyCase.getNumber(),
373 autopsyCase.getExaminer(),
374 autopsyCase.getExaminerEmail(),
375 autopsyCase.getExaminerPhone(),
376 autopsyCase.getCaseNotes());
377 return newCase(curCeCase);
381 public CorrelationCase getCase(Case autopsyCase)
throws CentralRepoException {
382 return getCaseByUUID(autopsyCase.getName());
391 public void updateCase(CorrelationCase eamCase)
throws CentralRepoException {
392 if (eamCase == null) {
393 throw new CentralRepoException(
"Correlation case is null");
396 Connection conn = connect();
398 PreparedStatement preparedStatement = null;
399 String sql =
"UPDATE cases "
400 +
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
401 +
"WHERE case_uid=?";
404 preparedStatement = conn.prepareStatement(sql);
406 if (null == eamCase.getOrg()) {
407 preparedStatement.setNull(1, Types.INTEGER);
409 preparedStatement.setInt(1, eamCase.getOrg().getOrgID());
411 preparedStatement.setString(2, eamCase.getDisplayName());
412 preparedStatement.setString(3, eamCase.getCreationDate());
414 if (
"".equals(eamCase.getCaseNumber())) {
415 preparedStatement.setNull(4, Types.INTEGER);
417 preparedStatement.setString(4, eamCase.getCaseNumber());
419 if (
"".equals(eamCase.getExaminerName())) {
420 preparedStatement.setNull(5, Types.INTEGER);
422 preparedStatement.setString(5, eamCase.getExaminerName());
424 if (
"".equals(eamCase.getExaminerEmail())) {
425 preparedStatement.setNull(6, Types.INTEGER);
427 preparedStatement.setString(6, eamCase.getExaminerEmail());
429 if (
"".equals(eamCase.getExaminerPhone())) {
430 preparedStatement.setNull(7, Types.INTEGER);
432 preparedStatement.setString(7, eamCase.getExaminerPhone());
434 if (
"".equals(eamCase.getNotes())) {
435 preparedStatement.setNull(8, Types.INTEGER);
437 preparedStatement.setString(8, eamCase.getNotes());
440 preparedStatement.setString(9, eamCase.getCaseUUID());
442 preparedStatement.executeUpdate();
444 caseCacheById.put(eamCase.getID(), eamCase);
445 caseCacheByUUID.put(eamCase.getCaseUUID(), eamCase);
446 }
catch (SQLException ex) {
447 throw new CentralRepoException(
"Error updating case.", ex);
449 CentralRepoDbUtil.closeStatement(preparedStatement);
450 CentralRepoDbUtil.closeConnection(conn);
462 public CorrelationCase getCaseByUUID(String caseUUID)
throws CentralRepoException {
464 return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
465 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
468 }
catch (ExecutionException ex) {
469 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
480 private CorrelationCase getCaseByUUIDFromCr(String caseUUID)
throws CentralRepoException {
481 Connection conn = connect();
483 CorrelationCase eamCaseResult = null;
484 PreparedStatement preparedStatement = null;
485 ResultSet resultSet = null;
487 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
488 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
490 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
491 +
"WHERE case_uid=?";
494 preparedStatement = conn.prepareStatement(sql);
495 preparedStatement.setString(1, caseUUID);
496 resultSet = preparedStatement.executeQuery();
497 if (resultSet.next()) {
498 eamCaseResult = getEamCaseFromResultSet(resultSet);
500 if (eamCaseResult != null) {
502 caseCacheById.put(eamCaseResult.getID(), eamCaseResult);
504 }
catch (SQLException ex) {
505 throw new CentralRepoException(
"Error getting case details.", ex);
507 CentralRepoDbUtil.closeStatement(preparedStatement);
508 CentralRepoDbUtil.closeResultSet(resultSet);
509 CentralRepoDbUtil.closeConnection(conn);
512 return eamCaseResult;
523 public CorrelationCase getCaseById(
int caseId)
throws CentralRepoException {
525 return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
526 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
529 }
catch (ExecutionException ex) {
530 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
541 private CorrelationCase getCaseByIdFromCr(
int caseId)
throws CentralRepoException {
542 Connection conn = connect();
544 CorrelationCase eamCaseResult = null;
545 PreparedStatement preparedStatement = null;
546 ResultSet resultSet = null;
548 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
549 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
551 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
552 +
"WHERE cases.id=?";
554 preparedStatement = conn.prepareStatement(sql);
555 preparedStatement.setInt(1, caseId);
556 resultSet = preparedStatement.executeQuery();
557 if (resultSet.next()) {
558 eamCaseResult = getEamCaseFromResultSet(resultSet);
560 if (eamCaseResult != null) {
562 caseCacheByUUID.put(eamCaseResult.getCaseUUID(), eamCaseResult);
564 }
catch (SQLException ex) {
565 throw new CentralRepoException(
"Error getting case details.", ex);
567 CentralRepoDbUtil.closeStatement(preparedStatement);
568 CentralRepoDbUtil.closeResultSet(resultSet);
569 CentralRepoDbUtil.closeConnection(conn);
572 return eamCaseResult;
581 public List<CorrelationCase> getCases() throws CentralRepoException {
582 Connection conn = connect();
584 List<CorrelationCase> cases =
new ArrayList<>();
585 CorrelationCase eamCaseResult;
586 PreparedStatement preparedStatement = null;
587 ResultSet resultSet = null;
589 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
590 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
592 +
"LEFT JOIN organizations ON cases.org_id=organizations.id";
595 preparedStatement = conn.prepareStatement(sql);
596 resultSet = preparedStatement.executeQuery();
597 while (resultSet.next()) {
598 eamCaseResult = getEamCaseFromResultSet(resultSet);
599 cases.add(eamCaseResult);
601 }
catch (SQLException ex) {
602 throw new CentralRepoException(
"Error getting all cases.", ex);
604 CentralRepoDbUtil.closeStatement(preparedStatement);
605 CentralRepoDbUtil.closeResultSet(resultSet);
606 CentralRepoDbUtil.closeConnection(conn);
622 private static String getDataSourceByDSObjectIdCacheKey(
int caseId, Long dataSourceObjectId) {
623 return "Case" + caseId +
"DsObjectId" + dataSourceObjectId;
635 private static String getDataSourceByIdCacheKey(
int caseId,
int dataSourceId) {
636 return "Case" + caseId +
"Id" + dataSourceId;
645 public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource)
throws CentralRepoException {
646 if (eamDataSource.getCaseID() == -1) {
647 throw new CentralRepoException(
"Case ID is -1");
649 if (eamDataSource.getDeviceID() == null) {
650 throw new CentralRepoException(
"Device ID is null");
652 if (eamDataSource.getName() == null) {
653 throw new CentralRepoException(
"Name is null");
655 if (eamDataSource.getID() != -1) {
657 return eamDataSource;
660 Connection conn = connect();
662 PreparedStatement preparedStatement = null;
664 String sql =
"INSERT INTO data_sources(device_id, case_id, name, datasource_obj_id, md5, sha1, sha256) VALUES (?, ?, ?, ?, ?, ?, ?) "
665 + getConflictClause();
666 ResultSet resultSet = null;
668 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
670 preparedStatement.setString(1, eamDataSource.getDeviceID());
671 preparedStatement.setInt(2, eamDataSource.getCaseID());
672 preparedStatement.setString(3, eamDataSource.getName());
673 preparedStatement.setLong(4, eamDataSource.getDataSourceObjectID());
674 preparedStatement.setString(5, eamDataSource.getMd5());
675 preparedStatement.setString(6, eamDataSource.getSha1());
676 preparedStatement.setString(7, eamDataSource.getSha256());
678 preparedStatement.executeUpdate();
679 resultSet = preparedStatement.getGeneratedKeys();
680 if (!resultSet.next()) {
689 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
690 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
691 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
692 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
693 throw new CentralRepoException(String.format(
"Unable to to INSERT or get data source %s in central repo:", eamDataSource.getName()), getException);
697 int dataSourceId = resultSet.getInt(1);
698 CorrelationDataSource dataSource =
new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getDataSourceObjectID(), eamDataSource.getMd5(), eamDataSource.getSha1(), eamDataSource.getSha256());
699 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(dataSource.getCaseID(), dataSource.getDataSourceObjectID()), dataSource);
700 dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource);
704 }
catch (SQLException insertException) {
714 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
715 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
716 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
717 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
718 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);
721 CentralRepoDbUtil.closeResultSet(resultSet);
722 CentralRepoDbUtil.closeStatement(preparedStatement);
723 CentralRepoDbUtil.closeConnection(conn);
739 public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long dataSourceObjectId)
throws CentralRepoException {
741 if (correlationCase == null) {
742 throw new CentralRepoException(
"Correlation case is null");
745 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), dataSourceObjectId), () -> getDataSourceFromCr(correlationCase.getID(), dataSourceObjectId));
746 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
749 }
catch (ExecutionException ex) {
750 throw new CentralRepoException(
"Error getting data source from central repository", ex);
766 private CorrelationDataSource getDataSourceFromCr(
int correlationCaseId, Long dataSourceObjectId)
throws CentralRepoException {
767 Connection conn = connect();
769 CorrelationDataSource eamDataSourceResult = null;
770 PreparedStatement preparedStatement = null;
771 ResultSet resultSet = null;
773 String sql =
"SELECT * FROM data_sources WHERE datasource_obj_id=? AND case_id=?";
776 preparedStatement = conn.prepareStatement(sql);
777 preparedStatement.setLong(1, dataSourceObjectId);
778 preparedStatement.setInt(2, correlationCaseId);
779 resultSet = preparedStatement.executeQuery();
780 if (resultSet.next()) {
781 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
783 if (eamDataSourceResult != null) {
784 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCaseId, eamDataSourceResult.getID()), eamDataSourceResult);
786 }
catch (SQLException ex) {
787 throw new CentralRepoException(
"Error getting data source.", ex);
789 CentralRepoDbUtil.closeStatement(preparedStatement);
790 CentralRepoDbUtil.closeResultSet(resultSet);
791 CentralRepoDbUtil.closeConnection(conn);
794 return eamDataSourceResult;
807 public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
808 if (correlationCase == null) {
809 throw new CentralRepoException(
"Correlation case is null");
812 return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
813 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
816 }
catch (ExecutionException ex) {
817 throw new CentralRepoException(
"Error getting data source from central repository", ex);
830 private CorrelationDataSource getDataSourceByIdFromCr(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
831 Connection conn = connect();
833 CorrelationDataSource eamDataSourceResult = null;
834 PreparedStatement preparedStatement = null;
835 ResultSet resultSet = null;
837 String sql =
"SELECT * FROM data_sources WHERE id=? AND case_id=?";
840 preparedStatement = conn.prepareStatement(sql);
841 preparedStatement.setInt(1, dataSourceId);
842 preparedStatement.setInt(2, correlationCase.getID());
843 resultSet = preparedStatement.executeQuery();
844 if (resultSet.next()) {
845 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
847 if (eamDataSourceResult != null) {
848 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDataSourceObjectID()), eamDataSourceResult);
850 }
catch (SQLException ex) {
851 throw new CentralRepoException(
"Error getting data source.", ex);
853 CentralRepoDbUtil.closeStatement(preparedStatement);
854 CentralRepoDbUtil.closeResultSet(resultSet);
855 CentralRepoDbUtil.closeConnection(conn);
858 return eamDataSourceResult;
867 public List<CorrelationDataSource> getDataSources() throws CentralRepoException {
868 Connection conn = connect();
870 List<CorrelationDataSource> dataSources =
new ArrayList<>();
871 CorrelationDataSource eamDataSourceResult;
872 PreparedStatement preparedStatement = null;
873 ResultSet resultSet = null;
875 String sql =
"SELECT * FROM data_sources";
878 preparedStatement = conn.prepareStatement(sql);
879 resultSet = preparedStatement.executeQuery();
880 while (resultSet.next()) {
881 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
882 dataSources.add(eamDataSourceResult);
884 }
catch (SQLException ex) {
885 throw new CentralRepoException(
"Error getting all data sources.", ex);
887 CentralRepoDbUtil.closeStatement(preparedStatement);
888 CentralRepoDbUtil.closeResultSet(resultSet);
889 CentralRepoDbUtil.closeConnection(conn);
901 public void updateDataSourceMd5Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
902 updateDataSourceStringValue(eamDataSource,
"md5", eamDataSource.getMd5());
911 public void updateDataSourceSha1Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
912 updateDataSourceStringValue(eamDataSource,
"sha1", eamDataSource.getSha1());
922 public void updateDataSourceSha256Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
923 updateDataSourceStringValue(eamDataSource,
"sha256", eamDataSource.getSha256());
933 private void updateDataSourceStringValue(CorrelationDataSource eamDataSource, String column, String value)
throws CentralRepoException {
934 if (eamDataSource == null) {
935 throw new CentralRepoException(
"Correlation data source is null");
938 Connection conn = connect();
940 PreparedStatement preparedStatement = null;
941 String sql =
"UPDATE data_sources "
942 +
"SET " + column +
"=? "
946 preparedStatement = conn.prepareStatement(sql);
948 preparedStatement.setString(1, value);
949 preparedStatement.setInt(2, eamDataSource.getID());
951 preparedStatement.executeUpdate();
953 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()), eamDataSource);
954 dataSourceCacheById.put(getDataSourceByIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getID()), eamDataSource);
955 }
catch (SQLException ex) {
956 throw new CentralRepoException(String.format(
"Error updating data source (obj_id=%d).", eamDataSource.getDataSourceObjectID()), ex);
958 CentralRepoDbUtil.closeStatement(preparedStatement);
959 CentralRepoDbUtil.closeConnection(conn);
972 public void updateDataSourceName(CorrelationDataSource eamDataSource, String newName)
throws CentralRepoException {
974 Connection conn = connect();
976 PreparedStatement preparedStatement = null;
978 String sql =
"UPDATE data_sources SET name = ? WHERE id = ?";
981 preparedStatement = conn.prepareStatement(sql);
982 preparedStatement.setString(1, newName);
983 preparedStatement.setInt(2, eamDataSource.getID());
984 preparedStatement.executeUpdate();
986 CorrelationDataSource updatedDataSource =
new CorrelationDataSource(
987 eamDataSource.getCaseID(),
988 eamDataSource.getID(),
989 eamDataSource.getDeviceID(),
991 eamDataSource.getDataSourceObjectID(),
992 eamDataSource.getMd5(),
993 eamDataSource.getSha1(),
994 eamDataSource.getSha256());
996 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getDataSourceObjectID()), updatedDataSource);
997 dataSourceCacheById.put(getDataSourceByIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getID()), updatedDataSource);
998 }
catch (SQLException ex) {
999 throw new CentralRepoException(
"Error updating name of data source with ID " + eamDataSource.getDataSourceObjectID()
1000 +
" to " + newName, ex);
1002 CentralRepoDbUtil.closeStatement(preparedStatement);
1003 CentralRepoDbUtil.closeConnection(conn);
1014 public void addArtifactInstance(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1015 checkAddArtifactInstanceNulls(eamArtifact);
1018 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1019 boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType());
1023 if (artifactHasAnAccount) {
1024 sql =
"INSERT INTO "
1026 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) "
1027 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
1028 + getConflictClause();
1030 sql =
"INSERT INTO "
1032 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1033 +
"VALUES (?, ?, ?, ?, ?, ?, ?) "
1034 + getConflictClause();
1037 try (Connection conn = connect();
1038 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1040 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1041 preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID());
1042 preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID());
1043 preparedStatement.setString(3, eamArtifact.getCorrelationValue());
1044 preparedStatement.setString(4, eamArtifact.getFilePath().toLowerCase());
1045 preparedStatement.setByte(5, eamArtifact.getKnownStatus().getFileKnownValue());
1047 if (
"".equals(eamArtifact.getComment())) {
1048 preparedStatement.setNull(6, Types.INTEGER);
1050 preparedStatement.setString(6, eamArtifact.getComment());
1052 preparedStatement.setLong(7, eamArtifact.getFileObjectId());
1055 if (artifactHasAnAccount) {
1056 if (eamArtifact.getAccountId() >= 0) {
1057 preparedStatement.setLong(8, eamArtifact.getAccountId());
1059 preparedStatement.setNull(8, Types.INTEGER);
1063 preparedStatement.executeUpdate();
1066 }
catch (SQLException ex) {
1067 throw new CentralRepoException(
"Error inserting new artifact into artifacts table.", ex);
1084 public CentralRepoAccount
getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1086 CentralRepoAccount account = getAccount(crAccountType, accountUniqueID);
1089 if (null == account) {
1091 String query =
"INSERT INTO accounts (account_type_id, account_unique_identifier) "
1092 +
"VALUES ( " + crAccountType.getAccountTypeId() +
", '"
1093 + accountUniqueID +
"' )";
1095 try (Connection connection = connect();
1096 Statement s = connection.createStatement();) {
1100 account = getAccount(crAccountType, accountUniqueID);
1101 }
catch (SQLException ex) {
1102 throw new CentralRepoException(
"Error adding an account to CR database.", ex);
1110 public CentralRepoAccountType getAccountTypeByName(String accountTypeName)
throws CentralRepoException {
1112 return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName));
1113 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
1114 throw new CentralRepoException(
"Error looking up CR account type in cache.", ex);
1119 public Collection<CentralRepoAccountType> getAllAccountTypes() throws CentralRepoException {
1121 Collection<CentralRepoAccountType> accountTypes =
new ArrayList<>();
1123 String sql =
"SELECT * FROM account_types";
1124 try (Connection conn = connect();
1125 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1127 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1128 while (resultSet.next()) {
1129 Account.Type acctType =
new Account.Type(resultSet.getString(
"type_name"), resultSet.getString(
"display_name"));
1130 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1132 accountTypes.add(crAccountType);
1135 }
catch (SQLException ex) {
1136 throw new CentralRepoException(
"Error getting account types from central repository.", ex);
1138 return accountTypes;
1150 private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName)
throws CentralRepoException {
1152 String sql =
"SELECT * FROM account_types WHERE type_name = ?";
1153 try (Connection conn = connect();
1154 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1156 preparedStatement.setString(1, accountTypeName);
1157 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1158 if (resultSet.next()) {
1159 Account.Type acctType =
new Account.Type(accountTypeName, resultSet.getString(
"display_name"));
1160 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1161 accountTypesCache.put(accountTypeName, crAccountType);
1162 return crAccountType;
1164 throw new CentralRepoException(
"Failed to find entry for account type = " + accountTypeName);
1167 }
catch (SQLException ex) {
1168 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
1188 private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1190 CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID));
1191 if (crAccount == null) {
1192 crAccount = getCRAccountFromDb(crAccountType, accountUniqueID);
1193 if (crAccount != null) {
1194 accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount);
1213 private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1215 CentralRepoAccount account = null;
1217 String sql =
"SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
1218 try (Connection connection = connect();
1219 PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
1221 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1222 preparedStatement.setString(2, accountUniqueID);
1224 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1225 if (resultSet.next()) {
1226 account =
new CentralRepoAccount(resultSet.getInt(
"id"), crAccountType, resultSet.getString(
"account_unique_identifier"));
1229 }
catch (SQLException ex) {
1230 throw new CentralRepoException(
"Error getting account type id", ex);
1236 private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1237 if (eamArtifact == null) {
1238 throw new CentralRepoException(
"CorrelationAttribute is null");
1240 if (eamArtifact.getCorrelationType() == null) {
1241 throw new CentralRepoException(
"Correlation type is null");
1243 if (eamArtifact.getCorrelationValue() == null) {
1244 throw new CentralRepoException(
"Correlation value is null");
1246 if (eamArtifact.getCorrelationValue().length() >= MAX_VALUE_LENGTH) {
1247 throw new CentralRepoException(
"Artifact value too long for central repository."
1248 +
"\nCorrelationArtifact ID: " + eamArtifact.getID()
1249 +
"\nCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1250 +
"\nCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1253 if (eamArtifact.getCorrelationCase() == null) {
1254 throw new CentralRepoException(
"CorrelationAttributeInstance case is null");
1256 if (eamArtifact.getCorrelationDataSource() == null) {
1257 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null");
1259 if (eamArtifact.getKnownStatus() == null) {
1260 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null");
1265 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1266 if (value == null) {
1267 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null value");
1269 return getArtifactInstancesByTypeValues(aType, Arrays.asList(value));
1273 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValues(CorrelationAttributeInstance.Type aType, List<String> values)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1274 if (aType == null) {
1275 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1277 if (values == null || values.isEmpty()) {
1278 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1280 return getArtifactInstances(prepareGetInstancesSql(aType, values), aType);
1284 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValuesAndCases(CorrelationAttributeInstance.Type aType, List<String> values, List<Integer> caseIds)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1285 if (aType == null) {
1286 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1288 if (values == null || values.isEmpty()) {
1289 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1291 if (caseIds == null || caseIds.isEmpty()) {
1292 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified cases");
1294 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1299 StringBuilder inValuesBuilder =
new StringBuilder(prepareGetInstancesSql(aType, values));
1300 inValuesBuilder.append(sql);
1301 inValuesBuilder.append(caseIds.stream().map(String::valueOf).collect(Collectors.joining(
"', '")));
1302 inValuesBuilder.append(
"')");
1303 return getArtifactInstances(inValuesBuilder.toString(), aType);
1318 private String prepareGetInstancesSql(CorrelationAttributeInstance.Type aType, List<String> values)
throws CorrelationAttributeNormalizationException {
1319 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1323 +
".id as instance_id,"
1328 +
" 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 "
1330 +
" LEFT JOIN cases ON "
1332 +
".case_id=cases.id"
1333 +
" LEFT JOIN organizations ON cases.org_id=organizations.id"
1334 +
" LEFT JOIN data_sources ON "
1336 +
".data_source_id=data_sources.id"
1337 +
" WHERE value IN (";
1338 StringBuilder inValuesBuilder =
new StringBuilder(sql);
1339 for (String value : values) {
1340 if (value != null) {
1341 inValuesBuilder.append(
"'");
1342 inValuesBuilder.append(CorrelationAttributeNormalizer.normalize(aType, value));
1343 inValuesBuilder.append(
"',");
1346 inValuesBuilder.deleteCharAt(inValuesBuilder.length() - 1);
1347 inValuesBuilder.append(
")");
1348 return inValuesBuilder.toString();
1365 private List<CorrelationAttributeInstance> getArtifactInstances(String sql, CorrelationAttributeInstance.Type aType) throws CorrelationAttributeNormalizationException, CentralRepoException {
1366 Connection conn = connect();
1367 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1368 CorrelationAttributeInstance artifactInstance;
1369 PreparedStatement preparedStatement = null;
1370 ResultSet resultSet = null;
1372 preparedStatement = conn.prepareStatement(sql);
1373 resultSet = preparedStatement.executeQuery();
1374 while (resultSet.next()) {
1375 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1376 artifactInstances.add(artifactInstance);
1378 }
catch (SQLException ex) {
1379 throw new CentralRepoException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
1381 CentralRepoDbUtil.closeStatement(preparedStatement);
1382 CentralRepoDbUtil.closeResultSet(resultSet);
1383 CentralRepoDbUtil.closeConnection(conn);
1385 return artifactInstances;
1399 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1400 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1402 Connection conn = connect();
1404 Long instanceCount = 0L;
1405 PreparedStatement preparedStatement = null;
1406 ResultSet resultSet = null;
1408 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1410 =
"SELECT count(*) FROM "
1415 preparedStatement = conn.prepareStatement(sql);
1416 preparedStatement.setString(1, normalizedValue);
1417 resultSet = preparedStatement.executeQuery();
1419 instanceCount = resultSet.getLong(1);
1420 }
catch (SQLException ex) {
1421 throw new CentralRepoException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1423 CentralRepoDbUtil.closeStatement(preparedStatement);
1424 CentralRepoDbUtil.closeResultSet(resultSet);
1425 CentralRepoDbUtil.closeConnection(conn);
1428 return instanceCount;
1432 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1433 if (corAttr == null) {
1434 throw new CentralRepoException(
"CorrelationAttribute is null");
1436 Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
1437 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1438 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1439 return commonalityPercentage.intValue();
1453 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1454 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1456 Connection conn = connect();
1458 Long instanceCount = 0L;
1459 PreparedStatement preparedStatement = null;
1460 ResultSet resultSet = null;
1462 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1464 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1466 +
" WHERE value=?) AS "
1468 +
"_distinct_case_data_source_tuple";
1471 preparedStatement = conn.prepareStatement(sql);
1472 preparedStatement.setString(1, normalizedValue);
1473 resultSet = preparedStatement.executeQuery();
1475 instanceCount = resultSet.getLong(1);
1476 }
catch (SQLException ex) {
1477 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1479 CentralRepoDbUtil.closeStatement(preparedStatement);
1480 CentralRepoDbUtil.closeResultSet(resultSet);
1481 CentralRepoDbUtil.closeConnection(conn);
1484 return instanceCount;
1488 public Long getCountUniqueDataSources() throws CentralRepoException {
1489 Connection conn = connect();
1491 Long instanceCount = 0L;
1492 PreparedStatement preparedStatement = null;
1493 ResultSet resultSet = null;
1495 String stmt =
"SELECT count(*) FROM data_sources";
1498 preparedStatement = conn.prepareStatement(stmt);
1499 resultSet = preparedStatement.executeQuery();
1501 instanceCount = resultSet.getLong(1);
1502 }
catch (SQLException ex) {
1503 throw new CentralRepoException(
"Error counting data sources.", ex);
1505 CentralRepoDbUtil.closeStatement(preparedStatement);
1506 CentralRepoDbUtil.closeResultSet(resultSet);
1507 CentralRepoDbUtil.closeConnection(conn);
1510 return instanceCount;
1525 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws CentralRepoException {
1526 Connection conn = connect();
1528 Long instanceCount = 0L;
1529 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1530 PreparedStatement preparedStatement = null;
1531 ResultSet resultSet = null;
1534 String sql =
"SELECT 0 ";
1536 for (CorrelationAttributeInstance.Type type : artifactTypes) {
1537 String table_name = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1539 +=
"+ (SELECT count(*) FROM "
1541 +
" WHERE data_source_id=" + correlationDataSource.getID() +
")";
1544 preparedStatement = conn.prepareStatement(sql);
1546 resultSet = preparedStatement.executeQuery();
1548 instanceCount = resultSet.getLong(1);
1549 }
catch (SQLException ex) {
1550 throw new CentralRepoException(
"Error counting artifact instances by caseName/dataSource.", ex);
1552 CentralRepoDbUtil.closeStatement(preparedStatement);
1553 CentralRepoDbUtil.closeResultSet(resultSet);
1554 CentralRepoDbUtil.closeConnection(conn);
1557 return instanceCount;
1568 public void addAttributeInstanceBulk(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1570 if (eamArtifact.getCorrelationType() == null) {
1571 throw new CentralRepoException(
"Correlation type is null");
1574 synchronized (bulkArtifacts) {
1575 if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
1576 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()),
new ArrayList<>());
1578 bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
1579 bulkArtifactsCount++;
1581 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1582 commitAttributeInstancesBulk();
1592 protected abstract String getConflictClause();
1599 public void commitAttributeInstancesBulk() throws CentralRepoException {
1600 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1602 Connection conn = connect();
1603 PreparedStatement bulkPs = null;
1606 synchronized (bulkArtifacts) {
1607 if (bulkArtifactsCount == 0) {
1611 for (String tableName : bulkArtifacts.keySet()) {
1616 +
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1617 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1618 +
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) "
1619 + getConflictClause();
1621 bulkPs = conn.prepareStatement(sql);
1623 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
1624 for (CorrelationAttributeInstance eamArtifact : eamArtifacts) {
1626 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1628 if (eamArtifact.getCorrelationCase() == null) {
1629 throw new CentralRepoException(
"CorrelationAttributeInstance case is null for: "
1630 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1631 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1632 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1634 if (eamArtifact.getCorrelationDataSource() == null) {
1635 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null for: "
1636 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1637 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1638 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1640 if (eamArtifact.getKnownStatus() == null) {
1641 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null for: "
1642 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1643 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1644 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue()
1645 +
"\n\tEam Instance: "
1646 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1647 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID());
1650 if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) {
1651 bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
1652 bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID());
1653 bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
1654 bulkPs.setString(4, eamArtifact.getCorrelationValue());
1655 bulkPs.setString(5, eamArtifact.getFilePath());
1656 bulkPs.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
1657 if (
"".equals(eamArtifact.getComment())) {
1658 bulkPs.setNull(7, Types.INTEGER);
1660 bulkPs.setString(7, eamArtifact.getComment());
1662 bulkPs.setLong(8, eamArtifact.getFileObjectId());
1665 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1666 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1667 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1668 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue())
1669 +
"\n\tEam Instance: "
1670 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1671 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID()
1672 +
"\n\t\tFilePath: " + eamArtifact.getFilePath());
1678 bulkPs.executeBatch();
1679 bulkArtifacts.get(tableName).clear();
1682 TimingMetric timingMetric = HealthMonitor.getTimingMetric(
"Central Repository: Bulk insert");
1683 HealthMonitor.submitTimingMetric(timingMetric);
1686 bulkArtifactsCount = 0;
1688 }
catch (SQLException ex) {
1689 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
1691 CentralRepoDbUtil.closeStatement(bulkPs);
1692 CentralRepoDbUtil.closeConnection(conn);
1700 public void bulkInsertCases(List<CorrelationCase> cases)
throws CentralRepoException {
1701 if (cases == null) {
1702 throw new CentralRepoException(
"cases argument is null");
1705 if (cases.isEmpty()) {
1709 Connection conn = connect();
1712 PreparedStatement bulkPs = null;
1714 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1715 +
"examiner_name, examiner_email, examiner_phone, notes) "
1716 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1717 + getConflictClause();
1718 bulkPs = conn.prepareStatement(sql);
1720 for (CorrelationCase eamCase : cases) {
1721 bulkPs.setString(1, eamCase.getCaseUUID());
1722 if (null == eamCase.getOrg()) {
1723 bulkPs.setNull(2, Types.INTEGER);
1725 bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1727 bulkPs.setString(3, eamCase.getDisplayName());
1728 bulkPs.setString(4, eamCase.getCreationDate());
1730 if (
"".equals(eamCase.getCaseNumber())) {
1731 bulkPs.setNull(5, Types.INTEGER);
1733 bulkPs.setString(5, eamCase.getCaseNumber());
1735 if (
"".equals(eamCase.getExaminerName())) {
1736 bulkPs.setNull(6, Types.INTEGER);
1738 bulkPs.setString(6, eamCase.getExaminerName());
1740 if (
"".equals(eamCase.getExaminerEmail())) {
1741 bulkPs.setNull(7, Types.INTEGER);
1743 bulkPs.setString(7, eamCase.getExaminerEmail());
1745 if (
"".equals(eamCase.getExaminerPhone())) {
1746 bulkPs.setNull(8, Types.INTEGER);
1748 bulkPs.setString(8, eamCase.getExaminerPhone());
1750 if (
"".equals(eamCase.getNotes())) {
1751 bulkPs.setNull(9, Types.INTEGER);
1753 bulkPs.setString(9, eamCase.getNotes());
1761 if (counter >= bulkArtifactsThreshold) {
1762 bulkPs.executeBatch();
1767 bulkPs.executeBatch();
1768 }
catch (SQLException ex) {
1769 throw new CentralRepoException(
"Error inserting bulk cases.", ex);
1771 CentralRepoDbUtil.closeStatement(bulkPs);
1772 CentralRepoDbUtil.closeConnection(conn);
1786 public void updateAttributeInstanceComment(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1788 if (eamArtifact == null) {
1789 throw new CentralRepoException(
"CorrelationAttributeInstance is null");
1791 if (eamArtifact.getCorrelationCase() == null) {
1792 throw new CentralRepoException(
"Correlation case is null");
1794 if (eamArtifact.getCorrelationDataSource() == null) {
1795 throw new CentralRepoException(
"Correlation data source is null");
1797 Connection conn = connect();
1798 PreparedStatement preparedQuery = null;
1799 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1804 +
"WHERE case_id=? "
1805 +
"AND data_source_id=? "
1807 +
"AND file_path=?";
1810 preparedQuery = conn.prepareStatement(sqlUpdate);
1811 preparedQuery.setString(1, eamArtifact.getComment());
1812 preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID());
1813 preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID());
1814 preparedQuery.setString(4, eamArtifact.getCorrelationValue());
1815 preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
1816 preparedQuery.executeUpdate();
1817 }
catch (SQLException ex) {
1818 throw new CentralRepoException(
"Error getting/setting artifact instance comment=" + eamArtifact.getComment(), ex);
1820 CentralRepoDbUtil.closeStatement(preparedQuery);
1821 CentralRepoDbUtil.closeConnection(conn);
1840 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1841 CorrelationDataSource correlationDataSource,
long objectID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1843 if (correlationCase == null) {
1844 throw new CentralRepoException(
"Correlation case is null");
1847 Connection conn = connect();
1849 PreparedStatement preparedStatement = null;
1850 ResultSet resultSet = null;
1851 CorrelationAttributeInstance correlationAttributeInstance = null;
1855 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1857 =
"SELECT id, value, file_path, known_status, comment FROM "
1859 +
" WHERE case_id=?"
1860 +
" AND file_obj_id=?";
1862 preparedStatement = conn.prepareStatement(sql);
1863 preparedStatement.setInt(1, correlationCase.getID());
1864 preparedStatement.setInt(2, (
int) objectID);
1865 resultSet = preparedStatement.executeQuery();
1866 if (resultSet.next()) {
1867 int instanceId = resultSet.getInt(1);
1868 String value = resultSet.getString(2);
1869 String filePath = resultSet.getString(3);
1870 int knownStatus = resultSet.getInt(4);
1871 String comment = resultSet.getString(5);
1873 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1874 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
1876 }
catch (SQLException ex) {
1877 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1879 CentralRepoDbUtil.closeStatement(preparedStatement);
1880 CentralRepoDbUtil.closeResultSet(resultSet);
1881 CentralRepoDbUtil.closeConnection(conn);
1884 return correlationAttributeInstance;
1902 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1903 CorrelationDataSource correlationDataSource, String value, String filePath)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1905 if (correlationCase == null) {
1906 throw new CentralRepoException(
"Correlation case is null");
1908 if (correlationDataSource == null) {
1909 throw new CentralRepoException(
"Correlation data source is null");
1911 if (filePath == null) {
1912 throw new CentralRepoException(
"Correlation file path is null");
1915 Connection conn = connect();
1917 PreparedStatement preparedStatement = null;
1918 ResultSet resultSet = null;
1919 CorrelationAttributeInstance correlationAttributeInstance = null;
1922 String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
1924 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1926 =
"SELECT id, known_status, comment FROM "
1928 +
" WHERE case_id=?"
1929 +
" AND data_source_id=?"
1931 +
" AND file_path=?";
1933 preparedStatement = conn.prepareStatement(sql);
1934 preparedStatement.setInt(1, correlationCase.getID());
1935 preparedStatement.setInt(2, correlationDataSource.getID());
1936 preparedStatement.setString(3, normalizedValue);
1937 preparedStatement.setString(4, filePath.toLowerCase());
1938 resultSet = preparedStatement.executeQuery();
1939 if (resultSet.next()) {
1940 int instanceId = resultSet.getInt(1);
1941 int knownStatus = resultSet.getInt(2);
1942 String comment = resultSet.getString(3);
1944 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1945 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
1947 }
catch (SQLException ex) {
1948 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1950 CentralRepoDbUtil.closeStatement(preparedStatement);
1951 CentralRepoDbUtil.closeResultSet(resultSet);
1952 CentralRepoDbUtil.closeConnection(conn);
1955 return correlationAttributeInstance;
1969 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws CentralRepoException {
1970 if (eamArtifact == null) {
1971 throw new CentralRepoException(
"CorrelationAttribute is null");
1973 if (knownStatus == null) {
1974 throw new CentralRepoException(
"Known status is null");
1977 if (eamArtifact.getCorrelationCase() == null) {
1978 throw new CentralRepoException(
"Correlation case is null");
1980 if (eamArtifact.getCorrelationDataSource() == null) {
1981 throw new CentralRepoException(
"Correlation data source is null");
1984 Connection conn = connect();
1986 PreparedStatement preparedUpdate = null;
1987 PreparedStatement preparedQuery = null;
1988 ResultSet resultSet = null;
1990 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1995 +
" WHERE case_id=? "
1996 +
"AND data_source_id=? "
1998 +
"AND file_path=?";
2003 +
" SET known_status=? WHERE id=?";
2006 preparedQuery = conn.prepareStatement(sqlQuery);
2007 preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID());
2008 preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID());
2009 preparedQuery.setString(3, eamArtifact.getCorrelationValue());
2010 preparedQuery.setString(4, eamArtifact.getFilePath());
2011 resultSet = preparedQuery.executeQuery();
2012 if (resultSet.next()) {
2013 int instance_id = resultSet.getInt(
"id");
2014 preparedUpdate = conn.prepareStatement(sqlUpdate);
2016 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
2017 preparedUpdate.setInt(2, instance_id);
2019 preparedUpdate.executeUpdate();
2026 CorrelationCase correlationCaseWithId = getCaseByUUID(eamArtifact.getCorrelationCase().getCaseUUID());
2027 if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) {
2028 newDataSource(eamArtifact.getCorrelationDataSource());
2030 eamArtifact.setKnownStatus(knownStatus);
2031 addArtifactInstance(eamArtifact);
2034 }
catch (SQLException ex) {
2035 throw new CentralRepoException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
2037 CentralRepoDbUtil.closeStatement(preparedUpdate);
2038 CentralRepoDbUtil.closeStatement(preparedQuery);
2039 CentralRepoDbUtil.closeResultSet(resultSet);
2040 CentralRepoDbUtil.closeConnection(conn);
2053 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2055 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2057 Connection conn = connect();
2059 Long badInstances = 0L;
2060 PreparedStatement preparedStatement = null;
2061 ResultSet resultSet = null;
2063 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2065 =
"SELECT count(*) FROM "
2067 +
" WHERE value=? AND known_status=?";
2070 preparedStatement = conn.prepareStatement(sql);
2071 preparedStatement.setString(1, normalizedValue);
2072 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2073 resultSet = preparedStatement.executeQuery();
2075 badInstances = resultSet.getLong(1);
2076 }
catch (SQLException ex) {
2077 throw new CentralRepoException(
"Error getting count of notable artifact instances.", ex);
2079 CentralRepoDbUtil.closeStatement(preparedStatement);
2080 CentralRepoDbUtil.closeResultSet(resultSet);
2081 CentralRepoDbUtil.closeConnection(conn);
2084 return badInstances;
2100 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2102 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2104 Connection conn = connect();
2106 Collection<String> caseNames =
new LinkedHashSet<>();
2108 PreparedStatement preparedStatement = null;
2109 ResultSet resultSet = null;
2111 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2113 =
"SELECT DISTINCT case_name FROM "
2115 +
" INNER JOIN cases ON "
2117 +
".case_id=cases.id WHERE "
2121 +
".known_status=?";
2124 preparedStatement = conn.prepareStatement(sql);
2125 preparedStatement.setString(1, normalizedValue);
2126 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2127 resultSet = preparedStatement.executeQuery();
2128 while (resultSet.next()) {
2129 caseNames.add(resultSet.getString(
"case_name"));
2131 }
catch (SQLException ex) {
2132 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2134 CentralRepoDbUtil.closeStatement(preparedStatement);
2135 CentralRepoDbUtil.closeResultSet(resultSet);
2136 CentralRepoDbUtil.closeConnection(conn);
2139 return caseNames.stream().collect(Collectors.toList());
2155 public List<String> getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2157 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2159 Connection conn = connect();
2161 Collection<String> caseNames =
new LinkedHashSet<>();
2163 PreparedStatement preparedStatement = null;
2164 ResultSet resultSet = null;
2166 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2168 =
"SELECT DISTINCT case_name FROM "
2170 +
" INNER JOIN cases ON "
2172 +
".case_id=cases.id WHERE "
2177 preparedStatement = conn.prepareStatement(sql);
2178 preparedStatement.setString(1, normalizedValue);
2179 resultSet = preparedStatement.executeQuery();
2180 while (resultSet.next()) {
2181 caseNames.add(resultSet.getString(
"case_name"));
2183 }
catch (SQLException ex) {
2184 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2186 CentralRepoDbUtil.closeStatement(preparedStatement);
2187 CentralRepoDbUtil.closeResultSet(resultSet);
2188 CentralRepoDbUtil.closeConnection(conn);
2191 return caseNames.stream().collect(Collectors.toList());
2202 public void deleteReferenceSet(
int referenceSetID)
throws CentralRepoException {
2203 deleteReferenceSetEntries(referenceSetID);
2204 deleteReferenceSetEntry(referenceSetID);
2214 private void deleteReferenceSetEntry(
int referenceSetID)
throws CentralRepoException {
2215 Connection conn = connect();
2217 PreparedStatement preparedStatement = null;
2218 String sql =
"DELETE FROM reference_sets WHERE id=?";
2221 preparedStatement = conn.prepareStatement(sql);
2222 preparedStatement.setInt(1, referenceSetID);
2223 preparedStatement.executeUpdate();
2224 }
catch (SQLException ex) {
2225 throw new CentralRepoException(
"Error deleting reference set " + referenceSetID, ex);
2227 CentralRepoDbUtil.closeStatement(preparedStatement);
2228 CentralRepoDbUtil.closeConnection(conn);
2240 private void deleteReferenceSetEntries(
int referenceSetID)
throws CentralRepoException {
2241 Connection conn = connect();
2243 PreparedStatement preparedStatement = null;
2244 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2247 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
2250 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2251 preparedStatement.setInt(1, referenceSetID);
2252 preparedStatement.executeUpdate();
2253 }
catch (SQLException ex) {
2254 throw new CentralRepoException(
"Error deleting files from reference set " + referenceSetID, ex);
2256 CentralRepoDbUtil.closeStatement(preparedStatement);
2257 CentralRepoDbUtil.closeConnection(conn);
2275 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws CentralRepoException {
2276 CentralRepoFileSet refSet = this.getReferenceSetByID(referenceSetID);
2277 if (refSet == null) {
2281 return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
2296 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2297 return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
2301 public HashHitInfo lookupHash(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2302 int correlationTypeID = CorrelationAttributeInstance.FILES_TYPE_ID;
2303 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), hash);
2305 Connection conn = connect();
2307 PreparedStatement preparedStatement = null;
2308 ResultSet resultSet = null;
2309 String sql =
"SELECT value,comment FROM %s WHERE value=? AND reference_set_id=?";
2311 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2314 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2315 preparedStatement.setString(1, normalizeValued);
2316 preparedStatement.setInt(2, referenceSetID);
2317 resultSet = preparedStatement.executeQuery();
2318 if (resultSet.next()) {
2319 String comment = resultSet.getString(
"comment");
2320 String hashFound = resultSet.getString(
"value");
2321 HashHitInfo found =
new HashHitInfo(hashFound,
"",
"");
2322 found.addComment(comment);
2327 }
catch (SQLException ex) {
2328 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2330 CentralRepoDbUtil.closeStatement(preparedStatement);
2331 CentralRepoDbUtil.closeResultSet(resultSet);
2332 CentralRepoDbUtil.closeConnection(conn);
2346 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2348 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
2350 Connection conn = connect();
2352 Long matchingInstances = 0L;
2353 PreparedStatement preparedStatement = null;
2354 ResultSet resultSet = null;
2355 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2357 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2360 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2361 preparedStatement.setString(1, normalizeValued);
2362 preparedStatement.setInt(2, referenceSetID);
2363 resultSet = preparedStatement.executeQuery();
2365 matchingInstances = resultSet.getLong(1);
2366 }
catch (SQLException ex) {
2367 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2369 CentralRepoDbUtil.closeStatement(preparedStatement);
2370 CentralRepoDbUtil.closeResultSet(resultSet);
2371 CentralRepoDbUtil.closeConnection(conn);
2374 return 0 < matchingInstances;
2386 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2389 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
2392 if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
2396 Connection conn = connect();
2398 Long badInstances = 0L;
2399 PreparedStatement preparedStatement = null;
2400 ResultSet resultSet = null;
2401 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2404 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2405 preparedStatement.setString(1, normalizeValued);
2406 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2407 resultSet = preparedStatement.executeQuery();
2409 badInstances = resultSet.getLong(1);
2410 }
catch (SQLException ex) {
2411 throw new CentralRepoException(
"Error determining if artifact is notable by reference.", ex);
2413 CentralRepoDbUtil.closeStatement(preparedStatement);
2414 CentralRepoDbUtil.closeResultSet(resultSet);
2415 CentralRepoDbUtil.closeConnection(conn);
2418 return 0 < badInstances;
2430 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2432 throw new CentralRepoException(
"Correlation type is null");
2435 if (instanceTableCallback == null) {
2436 throw new CentralRepoException(
"Callback interface is null");
2439 Connection conn = connect();
2440 PreparedStatement preparedStatement = null;
2441 ResultSet resultSet = null;
2442 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2443 StringBuilder sql =
new StringBuilder();
2444 sql.append(
"select * from ");
2445 sql.append(tableName);
2448 preparedStatement = conn.prepareStatement(sql.toString());
2449 resultSet = preparedStatement.executeQuery();
2450 instanceTableCallback.process(resultSet);
2451 }
catch (SQLException ex) {
2452 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2454 CentralRepoDbUtil.closeStatement(preparedStatement);
2455 CentralRepoDbUtil.closeResultSet(resultSet);
2456 CentralRepoDbUtil.closeConnection(conn);
2470 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2472 throw new CentralRepoException(
"Correlation type is null");
2475 if (instanceTableCallback == null) {
2476 throw new CentralRepoException(
"Callback interface is null");
2479 if (whereClause == null) {
2480 throw new CentralRepoException(
"Where clause is null");
2483 Connection conn = connect();
2484 PreparedStatement preparedStatement = null;
2485 ResultSet resultSet = null;
2486 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2487 StringBuilder sql =
new StringBuilder(300);
2488 sql.append(
"select * from ")
2491 .append(whereClause);
2494 preparedStatement = conn.prepareStatement(sql.toString());
2495 resultSet = preparedStatement.executeQuery();
2496 instanceTableCallback.process(resultSet);
2497 }
catch (SQLException ex) {
2498 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2500 CentralRepoDbUtil.closeStatement(preparedStatement);
2501 CentralRepoDbUtil.closeResultSet(resultSet);
2502 CentralRepoDbUtil.closeConnection(conn);
2515 public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2517 if (instanceTableCallback == null) {
2518 throw new CentralRepoException(
"Callback interface is null");
2521 if (selectClause == null) {
2522 throw new CentralRepoException(
"Select clause is null");
2525 Connection conn = connect();
2526 PreparedStatement preparedStatement = null;
2527 ResultSet resultSet = null;
2528 StringBuilder sql =
new StringBuilder(300);
2529 sql.append(
"select ")
2530 .append(selectClause);
2533 preparedStatement = conn.prepareStatement(sql.toString());
2534 resultSet = preparedStatement.executeQuery();
2535 instanceTableCallback.process(resultSet);
2536 }
catch (SQLException ex) {
2537 throw new CentralRepoException(
"Error running query", ex);
2539 CentralRepoDbUtil.closeStatement(preparedStatement);
2540 CentralRepoDbUtil.closeResultSet(resultSet);
2541 CentralRepoDbUtil.closeConnection(conn);
2546 public void executeInsertSQL(String insertClause)
throws CentralRepoException {
2548 if (insertClause == null) {
2549 throw new CentralRepoException(
"Insert SQL is null");
2552 String sql = getPlatformSpecificInsertSQL(insertClause);
2553 try (Connection conn = connect();
2554 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
2555 preparedStatement.executeUpdate();
2556 }
catch (SQLException ex) {
2557 throw new CentralRepoException(String.format(
"Error running SQL %s, exception = %s", sql, ex.getMessage()), ex);
2562 public void executeSelectSQL(String selectSQL, CentralRepositoryDbQueryCallback queryCallback)
throws CentralRepoException {
2563 if (queryCallback == null) {
2564 throw new CentralRepoException(
"Query callback is null");
2567 if (selectSQL == null) {
2568 throw new CentralRepoException(
"Select SQL is null");
2571 StringBuilder sqlSb =
new StringBuilder(QUERY_STR_MAX_LEN);
2572 if (selectSQL.trim().toUpperCase().startsWith(
"SELECT") ==
false) {
2573 sqlSb.append(
"SELECT ");
2576 sqlSb.append(selectSQL);
2578 try (Connection conn = connect();
2579 PreparedStatement preparedStatement = conn.prepareStatement(sqlSb.toString());
2580 ResultSet resultSet = preparedStatement.executeQuery();) {
2581 queryCallback.process(resultSet);
2582 }
catch (SQLException ex) {
2583 throw new CentralRepoException(String.format(
"Error running SQL %s, exception = %s", selectSQL, ex.getMessage()), ex);
2588 public void executeUpdateSQL(String updateSQL)
throws CentralRepoException {
2590 if (updateSQL == null) {
2591 throw new CentralRepoException(
"Update SQL is null");
2594 StringBuilder sqlSb =
new StringBuilder(QUERY_STR_MAX_LEN);
2595 if (updateSQL.trim().toUpperCase().startsWith(
"UPDATE") ==
false) {
2596 sqlSb.append(
"UPDATE ");
2599 sqlSb.append(updateSQL);
2601 try (Connection conn = connect();
2602 PreparedStatement preparedStatement = conn.prepareStatement(sqlSb.toString());) {
2603 preparedStatement.executeUpdate();
2604 }
catch (SQLException ex) {
2605 throw new CentralRepoException(String.format(
"Error running SQL %s, exception = %s", updateSQL, ex.getMessage()), ex);
2610 public void executeDeleteSQL(String deleteSQL)
throws CentralRepoException {
2612 if (deleteSQL == null) {
2613 throw new CentralRepoException(
"Delete SQL is null");
2616 StringBuilder sqlSb =
new StringBuilder(QUERY_STR_MAX_LEN);
2617 if (deleteSQL.trim().toUpperCase().startsWith(
"DELETE") ==
false) {
2618 sqlSb.append(
"DELETE ");
2621 sqlSb.append(deleteSQL);
2623 try (Connection conn = connect();
2624 PreparedStatement preparedStatement = conn.prepareStatement(sqlSb.toString());) {
2625 preparedStatement.executeUpdate();
2626 }
catch (SQLException ex) {
2627 throw new CentralRepoException(String.format(
"Error running SQL %s, exception = %s", deleteSQL, ex.getMessage()), ex);
2632 public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg)
throws CentralRepoException {
2633 if (eamOrg == null) {
2634 throw new CentralRepoException(
"EamOrganization is null");
2635 }
else if (eamOrg.getOrgID() != -1) {
2636 throw new CentralRepoException(
"EamOrganization already has an ID");
2639 Connection conn = connect();
2640 ResultSet generatedKeys = null;
2641 PreparedStatement preparedStatement = null;
2642 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2643 + getConflictClause();
2646 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2647 preparedStatement.setString(1, eamOrg.getName());
2648 preparedStatement.setString(2, eamOrg.getPocName());
2649 preparedStatement.setString(3, eamOrg.getPocEmail());
2650 preparedStatement.setString(4, eamOrg.getPocPhone());
2652 preparedStatement.executeUpdate();
2653 generatedKeys = preparedStatement.getGeneratedKeys();
2654 if (generatedKeys.next()) {
2655 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2658 throw new SQLException(
"Creating user failed, no ID obtained.");
2660 }
catch (SQLException ex) {
2661 throw new CentralRepoException(
"Error inserting new organization.", ex);
2663 CentralRepoDbUtil.closeStatement(preparedStatement);
2664 CentralRepoDbUtil.closeResultSet(generatedKeys);
2665 CentralRepoDbUtil.closeConnection(conn);
2677 public List<CentralRepoOrganization> getOrganizations() throws CentralRepoException {
2678 Connection conn = connect();
2680 List<CentralRepoOrganization> orgs =
new ArrayList<>();
2681 PreparedStatement preparedStatement = null;
2682 ResultSet resultSet = null;
2683 String sql =
"SELECT * FROM organizations";
2686 preparedStatement = conn.prepareStatement(sql);
2687 resultSet = preparedStatement.executeQuery();
2688 while (resultSet.next()) {
2689 orgs.add(getEamOrganizationFromResultSet(resultSet));
2693 }
catch (SQLException ex) {
2694 throw new CentralRepoException(
"Error getting all organizations.", ex);
2696 CentralRepoDbUtil.closeStatement(preparedStatement);
2697 CentralRepoDbUtil.closeResultSet(resultSet);
2698 CentralRepoDbUtil.closeConnection(conn);
2712 public CentralRepoOrganization getOrganizationByID(
int orgID)
throws CentralRepoException {
2713 Connection conn = connect();
2715 PreparedStatement preparedStatement = null;
2716 ResultSet resultSet = null;
2717 String sql =
"SELECT * FROM organizations WHERE id=?";
2720 preparedStatement = conn.prepareStatement(sql);
2721 preparedStatement.setInt(1, orgID);
2722 resultSet = preparedStatement.executeQuery();
2724 return getEamOrganizationFromResultSet(resultSet);
2726 }
catch (SQLException ex) {
2727 throw new CentralRepoException(
"Error getting organization by id.", ex);
2729 CentralRepoDbUtil.closeStatement(preparedStatement);
2730 CentralRepoDbUtil.closeResultSet(resultSet);
2731 CentralRepoDbUtil.closeConnection(conn);
2745 public CentralRepoOrganization getReferenceSetOrganization(
int referenceSetID)
throws CentralRepoException {
2747 CentralRepoFileSet globalSet = getReferenceSetByID(referenceSetID);
2748 if (globalSet == null) {
2749 throw new CentralRepoException(
"Reference set with ID " + referenceSetID +
" not found");
2751 return (getOrganizationByID(globalSet.getOrgID()));
2761 private void testArgument(CentralRepoOrganization
org)
throws CentralRepoException {
2763 throw new CentralRepoException(
"EamOrganization is null");
2764 }
else if (
org.getOrgID() == -1) {
2765 throw new CentralRepoException(
"Organization has -1 row ID");
2781 public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName)
throws CentralRepoException {
2783 String querySQL =
"SELECT * FROM examiners WHERE login_name = '" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"'";
2784 try (Connection connection = connect();
2785 Statement statement = connection.createStatement();
2786 ResultSet resultSet = statement.executeQuery(querySQL);) {
2788 if (resultSet.next()) {
2789 return new CentralRepoExaminer(resultSet.getLong(
"id"), resultSet.getString(
"login_name"));
2794 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
2796 insertSQL =
"INSERT INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')" + getConflictClause();
2799 insertSQL =
"INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) +
"')";
2802 throw new CentralRepoException(String.format(
"Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
2804 statement.execute(insertSQL);
2807 try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
2808 if (resultSet2.next()) {
2809 return new CentralRepoExaminer(resultSet2.getLong(
"id"), resultSet2.getString(
"login_name"));
2811 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName);
2815 }
catch (SQLException ex) {
2816 throw new CentralRepoException(
"Error inserting row in examiners", ex);
2820 }
catch (SQLException ex) {
2821 throw new CentralRepoException(
"Error getting examiner for name = " + examinerLoginName, ex);
2834 public void updateOrganization(CentralRepoOrganization updatedOrganization)
throws CentralRepoException {
2835 testArgument(updatedOrganization);
2837 Connection conn = connect();
2838 PreparedStatement preparedStatement = null;
2839 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2841 preparedStatement = conn.prepareStatement(sql);
2842 preparedStatement.setString(1, updatedOrganization.getName());
2843 preparedStatement.setString(2, updatedOrganization.getPocName());
2844 preparedStatement.setString(3, updatedOrganization.getPocEmail());
2845 preparedStatement.setString(4, updatedOrganization.getPocPhone());
2846 preparedStatement.setInt(5, updatedOrganization.getOrgID());
2847 preparedStatement.executeUpdate();
2848 }
catch (SQLException ex) {
2849 throw new CentralRepoException(
"Error updating organization.", ex);
2851 CentralRepoDbUtil.closeStatement(preparedStatement);
2852 CentralRepoDbUtil.closeConnection(conn);
2857 public void deleteOrganization(CentralRepoOrganization organizationToDelete)
throws CentralRepoException {
2858 testArgument(organizationToDelete);
2860 Connection conn = connect();
2861 PreparedStatement checkIfUsedStatement = null;
2862 ResultSet resultSet = null;
2863 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2864 PreparedStatement deleteOrgStatement = null;
2865 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2867 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2868 checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
2869 checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
2870 resultSet = checkIfUsedStatement.executeQuery();
2872 if (resultSet.getLong(1) > 0) {
2873 throw new CentralRepoException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2875 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2876 deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
2877 deleteOrgStatement.executeUpdate();
2878 }
catch (SQLException ex) {
2879 throw new CentralRepoException(
"Error executing query when attempting to delete organization by id.", ex);
2881 CentralRepoDbUtil.closeStatement(checkIfUsedStatement);
2882 CentralRepoDbUtil.closeStatement(deleteOrgStatement);
2883 CentralRepoDbUtil.closeResultSet(resultSet);
2884 CentralRepoDbUtil.closeConnection(conn);
2898 public int newReferenceSet(CentralRepoFileSet eamGlobalSet)
throws CentralRepoException {
2899 if (eamGlobalSet == null) {
2900 throw new CentralRepoException(
"EamGlobalSet is null");
2903 if (eamGlobalSet.getFileKnownStatus() == null) {
2904 throw new CentralRepoException(
"File known status on the EamGlobalSet is null");
2907 if (eamGlobalSet.getType() == null) {
2908 throw new CentralRepoException(
"Type on the EamGlobalSet is null");
2911 Connection conn = connect();
2913 PreparedStatement preparedStatement1 = null;
2914 PreparedStatement preparedStatement2 = null;
2915 ResultSet resultSet = null;
2916 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2917 + getConflictClause();
2918 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2921 preparedStatement1 = conn.prepareStatement(sql1);
2922 preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
2923 preparedStatement1.setString(2, eamGlobalSet.getSetName());
2924 preparedStatement1.setString(3, eamGlobalSet.getVersion());
2925 preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
2926 preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
2927 preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
2928 preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
2930 preparedStatement1.executeUpdate();
2932 preparedStatement2 = conn.prepareStatement(sql2);
2933 preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
2934 preparedStatement2.setString(2, eamGlobalSet.getSetName());
2935 preparedStatement2.setString(3, eamGlobalSet.getVersion());
2936 preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
2938 resultSet = preparedStatement2.executeQuery();
2940 return resultSet.getInt(
"id");
2942 }
catch (SQLException ex) {
2943 throw new CentralRepoException(
"Error inserting new global set.", ex);
2945 CentralRepoDbUtil.closeStatement(preparedStatement1);
2946 CentralRepoDbUtil.closeStatement(preparedStatement2);
2947 CentralRepoDbUtil.closeResultSet(resultSet);
2948 CentralRepoDbUtil.closeConnection(conn);
2962 public CentralRepoFileSet getReferenceSetByID(
int referenceSetID)
throws CentralRepoException {
2963 Connection conn = connect();
2965 PreparedStatement preparedStatement1 = null;
2966 ResultSet resultSet = null;
2967 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2970 preparedStatement1 = conn.prepareStatement(sql1);
2971 preparedStatement1.setInt(1, referenceSetID);
2972 resultSet = preparedStatement1.executeQuery();
2973 if (resultSet.next()) {
2974 return getEamGlobalSetFromResultSet(resultSet);
2979 }
catch (SQLException ex) {
2980 throw new CentralRepoException(
"Error getting reference set by id.", ex);
2982 CentralRepoDbUtil.closeStatement(preparedStatement1);
2983 CentralRepoDbUtil.closeResultSet(resultSet);
2984 CentralRepoDbUtil.closeConnection(conn);
2998 public List<CentralRepoFileSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3000 if (correlationType == null) {
3001 throw new CentralRepoException(
"Correlation type is null");
3004 List<CentralRepoFileSet> results =
new ArrayList<>();
3005 Connection conn = connect();
3007 PreparedStatement preparedStatement1 = null;
3008 ResultSet resultSet = null;
3009 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
3012 preparedStatement1 = conn.prepareStatement(sql1);
3013 resultSet = preparedStatement1.executeQuery();
3014 while (resultSet.next()) {
3015 results.add(getEamGlobalSetFromResultSet(resultSet));
3018 }
catch (SQLException ex) {
3019 throw new CentralRepoException(
"Error getting reference sets.", ex);
3021 CentralRepoDbUtil.closeStatement(preparedStatement1);
3022 CentralRepoDbUtil.closeResultSet(resultSet);
3023 CentralRepoDbUtil.closeConnection(conn);
3038 public void addReferenceInstance(CentralRepoFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
3039 if (eamGlobalFileInstance.getKnownStatus() == null) {
3040 throw new CentralRepoException(
"Known status of EamGlobalFileInstance is null");
3042 if (correlationType == null) {
3043 throw new CentralRepoException(
"Correlation type is null");
3046 Connection conn = connect();
3048 PreparedStatement preparedStatement = null;
3050 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3051 + getConflictClause();
3054 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(correlationType)));
3055 preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
3056 preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
3057 preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
3058 preparedStatement.setString(4, eamGlobalFileInstance.getComment());
3059 preparedStatement.executeUpdate();
3060 }
catch (SQLException ex) {
3061 throw new CentralRepoException(
"Error inserting new reference instance into reference_ table.", ex);
3063 CentralRepoDbUtil.closeStatement(preparedStatement);
3064 CentralRepoDbUtil.closeConnection(conn);
3081 public boolean referenceSetExists(String referenceSetName, String version)
throws CentralRepoException {
3082 Connection conn = connect();
3084 PreparedStatement preparedStatement1 = null;
3085 ResultSet resultSet = null;
3086 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
3089 preparedStatement1 = conn.prepareStatement(sql1);
3090 preparedStatement1.setString(1, referenceSetName);
3091 preparedStatement1.setString(2, version);
3092 resultSet = preparedStatement1.executeQuery();
3093 return (resultSet.next());
3095 }
catch (SQLException ex) {
3096 throw new CentralRepoException(
"Error testing whether reference set exists (name: " + referenceSetName
3097 +
" version: " + version, ex);
3099 CentralRepoDbUtil.closeStatement(preparedStatement1);
3100 CentralRepoDbUtil.closeResultSet(resultSet);
3101 CentralRepoDbUtil.closeConnection(conn);
3111 public void bulkInsertReferenceTypeEntries(Set<CentralRepoFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws CentralRepoException {
3112 if (contentType == null) {
3113 throw new CentralRepoException(
"Correlation type is null");
3115 if (globalInstances == null) {
3116 throw new CentralRepoException(
"Null set of EamGlobalFileInstance");
3119 Connection conn = connect();
3121 PreparedStatement bulkPs = null;
3123 conn.setAutoCommit(
false);
3126 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
3127 + getConflictClause();
3129 bulkPs = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(contentType)));
3131 for (CentralRepoFileInstance globalInstance : globalInstances) {
3132 if (globalInstance.getKnownStatus() == null) {
3133 throw new CentralRepoException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
3136 bulkPs.setInt(1, globalInstance.getGlobalSetID());
3137 bulkPs.setString(2, globalInstance.getMD5Hash());
3138 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
3139 bulkPs.setString(4, globalInstance.getComment());
3143 bulkPs.executeBatch();
3145 }
catch (SQLException | CentralRepoException ex) {
3148 }
catch (SQLException ex2) {
3151 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
3153 CentralRepoDbUtil.closeStatement(bulkPs);
3154 CentralRepoDbUtil.closeConnection(conn);
3169 public List<CentralRepoFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws CentralRepoException, CorrelationAttributeNormalizationException {
3170 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
3172 Connection conn = connect();
3174 List<CentralRepoFileInstance> globalFileInstances =
new ArrayList<>();
3175 PreparedStatement preparedStatement1 = null;
3176 ResultSet resultSet = null;
3177 String sql1 =
"SELECT * FROM %s WHERE value=?";
3180 preparedStatement1 = conn.prepareStatement(String.format(sql1, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
3181 preparedStatement1.setString(1, normalizeValued);
3182 resultSet = preparedStatement1.executeQuery();
3183 while (resultSet.next()) {
3184 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
3187 }
catch (SQLException ex) {
3188 throw new CentralRepoException(
"Error getting reference instances by type and value.", ex);
3190 CentralRepoDbUtil.closeStatement(preparedStatement1);
3191 CentralRepoDbUtil.closeResultSet(resultSet);
3192 CentralRepoDbUtil.closeConnection(conn);
3195 return globalFileInstances;
3208 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3209 if (newType == null) {
3210 throw new CentralRepoException(
"Correlation type is null");
3213 if (-1 == newType.getId()) {
3214 typeId = newCorrelationTypeNotKnownId(newType);
3216 typeId = newCorrelationTypeKnownId(newType);
3219 synchronized (typeCache) {
3220 typeCache.put(newType.getId(), newType);
3235 public int newCorrelationTypeNotKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3236 Connection conn = connect();
3238 PreparedStatement preparedStatement = null;
3239 PreparedStatement preparedStatementQuery = null;
3240 ResultSet resultSet = null;
3245 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
3247 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3250 preparedStatement = conn.prepareStatement(insertSql);
3252 preparedStatement.setString(1, newType.getDisplayName());
3253 preparedStatement.setString(2, newType.getDbTableName());
3254 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
3255 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
3257 preparedStatement.executeUpdate();
3259 preparedStatementQuery = conn.prepareStatement(querySql);
3260 preparedStatementQuery.setString(1, newType.getDisplayName());
3261 preparedStatementQuery.setString(2, newType.getDbTableName());
3263 resultSet = preparedStatementQuery.executeQuery();
3264 if (resultSet.next()) {
3265 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3266 typeId = correlationType.getId();
3268 }
catch (SQLException ex) {
3269 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3271 CentralRepoDbUtil.closeStatement(preparedStatement);
3272 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3273 CentralRepoDbUtil.closeResultSet(resultSet);
3274 CentralRepoDbUtil.closeConnection(conn);
3288 private int newCorrelationTypeKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3289 Connection conn = connect();
3291 PreparedStatement preparedStatement = null;
3292 PreparedStatement preparedStatementQuery = null;
3293 ResultSet resultSet = null;
3298 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3300 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3303 preparedStatement = conn.prepareStatement(insertSql);
3305 preparedStatement.setInt(1, newType.getId());
3306 preparedStatement.setString(2, newType.getDisplayName());
3307 preparedStatement.setString(3, newType.getDbTableName());
3308 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
3309 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
3311 preparedStatement.executeUpdate();
3313 preparedStatementQuery = conn.prepareStatement(querySql);
3314 preparedStatementQuery.setString(1, newType.getDisplayName());
3315 preparedStatementQuery.setString(2, newType.getDbTableName());
3317 resultSet = preparedStatementQuery.executeQuery();
3318 if (resultSet.next()) {
3319 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3320 typeId = correlationType.getId();
3322 }
catch (SQLException ex) {
3323 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3325 CentralRepoDbUtil.closeStatement(preparedStatement);
3326 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3327 CentralRepoDbUtil.closeResultSet(resultSet);
3328 CentralRepoDbUtil.closeConnection(conn);
3334 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws CentralRepoException {
3336 synchronized (typeCache) {
3337 if (isCRTypeCacheInitialized ==
false) {
3338 getCorrelationTypesFromCr();
3340 return new ArrayList<>(typeCache.asMap().values());
3354 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws CentralRepoException {
3355 Connection conn = connect();
3357 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3358 PreparedStatement preparedStatement = null;
3359 ResultSet resultSet = null;
3360 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3363 preparedStatement = conn.prepareStatement(sql);
3364 resultSet = preparedStatement.executeQuery();
3365 while (resultSet.next()) {
3366 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3370 }
catch (SQLException ex) {
3371 throw new CentralRepoException(
"Error getting enabled correlation types.", ex);
3373 CentralRepoDbUtil.closeStatement(preparedStatement);
3374 CentralRepoDbUtil.closeResultSet(resultSet);
3375 CentralRepoDbUtil.closeConnection(conn);
3389 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws CentralRepoException {
3390 Connection conn = connect();
3392 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3393 PreparedStatement preparedStatement = null;
3394 ResultSet resultSet = null;
3395 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3398 preparedStatement = conn.prepareStatement(sql);
3399 resultSet = preparedStatement.executeQuery();
3400 while (resultSet.next()) {
3401 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3405 }
catch (SQLException ex) {
3406 throw new CentralRepoException(
"Error getting supported correlation types.", ex);
3408 CentralRepoDbUtil.closeStatement(preparedStatement);
3409 CentralRepoDbUtil.closeResultSet(resultSet);
3410 CentralRepoDbUtil.closeConnection(conn);
3422 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws CentralRepoException {
3423 Connection conn = connect();
3425 PreparedStatement preparedStatement = null;
3426 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3429 preparedStatement = conn.prepareStatement(sql);
3430 preparedStatement.setString(1, aType.getDisplayName());
3431 preparedStatement.setString(2, aType.getDbTableName());
3432 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3433 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3434 preparedStatement.setInt(5, aType.getId());
3435 preparedStatement.executeUpdate();
3436 synchronized (typeCache) {
3437 typeCache.put(aType.getId(), aType);
3439 }
catch (SQLException ex) {
3440 throw new CentralRepoException(
"Error updating correlation type.", ex);
3442 CentralRepoDbUtil.closeStatement(preparedStatement);
3443 CentralRepoDbUtil.closeConnection(conn);
3458 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws CentralRepoException {
3460 synchronized (typeCache) {
3461 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3463 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3466 }
catch (ExecutionException ex) {
3467 throw new CentralRepoException(
"Error getting correlation type", ex);
3480 private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(
int typeId)
throws CentralRepoException {
3481 Connection conn = connect();
3483 CorrelationAttributeInstance.Type aType;
3484 PreparedStatement preparedStatement = null;
3485 ResultSet resultSet = null;
3486 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3489 preparedStatement = conn.prepareStatement(sql);
3490 preparedStatement.setInt(1, typeId);
3491 resultSet = preparedStatement.executeQuery();
3492 if (resultSet.next()) {
3493 aType = getCorrelationTypeFromResultSet(resultSet);
3496 throw new CentralRepoException(
"Failed to find entry for correlation type ID = " + typeId);
3499 }
catch (SQLException ex) {
3500 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
3502 CentralRepoDbUtil.closeStatement(preparedStatement);
3503 CentralRepoDbUtil.closeResultSet(resultSet);
3504 CentralRepoDbUtil.closeConnection(conn);
3514 private void getCorrelationTypesFromCr() throws CentralRepoException {
3517 synchronized (typeCache) {
3518 typeCache.invalidateAll();
3519 isCRTypeCacheInitialized =
false;
3522 String sql =
"SELECT * FROM correlation_types";
3523 try (Connection conn = connect();
3524 PreparedStatement preparedStatement = conn.prepareStatement(sql);
3525 ResultSet resultSet = preparedStatement.executeQuery();) {
3527 synchronized (typeCache) {
3528 while (resultSet.next()) {
3529 CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
3530 typeCache.put(aType.getId(), aType);
3532 isCRTypeCacheInitialized =
true;
3534 }
catch (SQLException ex) {
3535 throw new CentralRepoException(
"Error getting correlation types.", ex);
3549 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3550 if (null == resultSet) {
3554 CentralRepoOrganization eamOrg = null;
3556 resultSet.getInt(
"org_id");
3557 if (!resultSet.wasNull()) {
3559 eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3560 resultSet.getString(
"org_name"),
3561 resultSet.getString(
"poc_name"),
3562 resultSet.getString(
"poc_email"),
3563 resultSet.getString(
"poc_phone"));
3566 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3567 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3568 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3573 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3574 if (null == resultSet) {
3578 CorrelationDataSource eamDataSource =
new CorrelationDataSource(
3579 resultSet.getInt(
"case_id"),
3580 resultSet.getInt(
"id"),
3581 resultSet.getString(
"device_id"),
3582 resultSet.getString(
"name"),
3583 resultSet.getLong(
"datasource_obj_id"),
3584 resultSet.getString(
"md5"),
3585 resultSet.getString(
"sha1"),
3586 resultSet.getString(
"sha256")
3589 return eamDataSource;
3592 private CorrelationAttributeInstance.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
throws CentralRepoException, SQLException {
3593 if (null == resultSet) {
3597 CorrelationAttributeInstance.Type eamArtifactType =
new CorrelationAttributeInstance.Type(
3598 resultSet.getInt(
"id"),
3599 resultSet.getString(
"display_name"),
3600 resultSet.getString(
"db_table_name"),
3601 resultSet.getBoolean(
"supported"),
3602 resultSet.getBoolean(
"enabled")
3605 return eamArtifactType;
3618 private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3619 if (null == resultSet) {
3623 CentralRepoOrganization eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3624 resultSet.getString(
"org_name"),
3625 resultSet.getString(
"poc_name"),
3626 resultSet.getString(
"poc_email"),
3627 resultSet.getString(
"poc_phone"));
3629 return new CorrelationAttributeInstance(
3631 resultSet.getString(
"value"),
3632 resultSet.getInt(
"instance_id"),
3633 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3634 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3635 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3636 new CorrelationDataSource(
3637 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3638 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3639 resultSet.getString(
"file_path"),
3640 resultSet.getString(
"comment"),
3641 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3642 resultSet.getLong(
"file_obj_id"));
3645 private CentralRepoOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3646 if (null == resultSet) {
3650 return new CentralRepoOrganization(
3651 resultSet.getInt(
"id"),
3652 resultSet.getString(
"org_name"),
3653 resultSet.getString(
"poc_name"),
3654 resultSet.getString(
"poc_email"),
3655 resultSet.getString(
"poc_phone")
3659 private CentralRepoFileSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException {
3660 if (null == resultSet) {
3664 return new CentralRepoFileSet(
3665 resultSet.getInt(
"id"),
3666 resultSet.getInt(
"org_id"),
3667 resultSet.getString(
"set_name"),
3668 resultSet.getString(
"version"),
3669 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3670 resultSet.getBoolean(
"read_only"),
3671 CentralRepository.getInstance().getCorrelationTypeById(resultSet.getInt(
"type")),
3672 LocalDate.parse(resultSet.getString(
"import_date"))
3676 private CentralRepoFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3677 if (null == resultSet) {
3681 return new CentralRepoFileInstance(
3682 resultSet.getInt(
"id"),
3683 resultSet.getInt(
"reference_set_id"),
3684 resultSet.getString(
"value"),
3685 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3686 resultSet.getString(
"comment")
3690 private String getPlatformSpecificInsertSQL(String sql)
throws CentralRepoException {
3692 switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
3694 return "INSERT " + sql +
" ON CONFLICT DO NOTHING";
3696 return "INSERT OR IGNORE " + sql;
3699 throw new CentralRepoException(
"Unknown Central Repo DB platform" + CentralRepoDbManager.getSavedDbChoice().getDbPlatform());
3713 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3720 @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.",
3721 "# {0} - minorVersion",
3722 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3723 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3724 "# {0} - majorVersion",
3725 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3726 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3727 "# {0} - platformName",
3728 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3730 public void upgradeSchema() throws CentralRepoException, SQLException, IncompatibleCentralRepoException {
3732 ResultSet resultSet = null;
3733 Statement statement = null;
3734 PreparedStatement preparedStatement = null;
3735 Connection conn = null;
3736 CentralRepoPlatforms selectedPlatform = null;
3739 conn = connect(
false);
3740 conn.setAutoCommit(
false);
3741 statement = conn.createStatement();
3742 selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
3743 int minorVersion = 0;
3744 String minorVersionStr = null;
3745 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"'");
3746 if (resultSet.next()) {
3747 minorVersionStr = resultSet.getString(
"value");
3749 minorVersion = Integer.parseInt(minorVersionStr);
3750 }
catch (NumberFormatException ex) {
3751 throw new CentralRepoException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3754 throw new CentralRepoException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3757 int majorVersion = 0;
3758 String majorVersionStr = null;
3759 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"'");
3760 if (resultSet.next()) {
3761 majorVersionStr = resultSet.getString(
"value");
3763 majorVersion = Integer.parseInt(majorVersionStr);
3764 }
catch (NumberFormatException ex) {
3765 throw new CentralRepoException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3768 throw new CentralRepoException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3779 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3784 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3785 throw new IncompatibleCentralRepoException(Bundle.AbstractSqlEamDb_upgradeSchema_incompatible());
3787 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3788 logger.log(Level.INFO,
"Central Repository is up to date");
3791 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3792 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3799 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3800 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3801 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3802 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3807 CentralRepoDbUtil.insertDefaultOrganization(conn);
3813 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3814 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3816 final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
3817 final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
3818 final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
3819 final String addValueIndexTemplate = RdbmsCentralRepoFactory.getAddValueIndexTemplate();
3820 final String addKnownStatusIndexTemplate = RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate();
3821 final String addObjectIdIndexTemplate = RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate();
3823 final String addAttributeSql;
3825 switch (selectedPlatform) {
3827 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3830 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3833 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3836 final String dataSourcesTableName =
"data_sources";
3837 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3838 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3839 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3841 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3842 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3843 List<String> instaceTablesToAdd =
new ArrayList<>();
3845 final String wirelessNetworksDbTableName =
"wireless_networks";
3846 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3847 final String macAddressDbTableName =
"mac_address";
3848 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3849 final String imeiNumberDbTableName =
"imei_number";
3850 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3851 final String iccidNumberDbTableName =
"iccid_number";
3852 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3853 final String imsiNumberDbTableName =
"imsi_number";
3854 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3857 preparedStatement = conn.prepareStatement(addAttributeSql);
3858 preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID);
3859 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3860 preparedStatement.setString(3, wirelessNetworksDbTableName);
3861 preparedStatement.setInt(4, 1);
3862 preparedStatement.setInt(5, 1);
3863 preparedStatement.execute();
3866 preparedStatement = conn.prepareStatement(addAttributeSql);
3867 preparedStatement.setInt(1, CorrelationAttributeInstance.MAC_TYPE_ID);
3868 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3869 preparedStatement.setString(3, macAddressDbTableName);
3870 preparedStatement.setInt(4, 1);
3871 preparedStatement.setInt(5, 1);
3872 preparedStatement.execute();
3875 preparedStatement = conn.prepareStatement(addAttributeSql);
3876 preparedStatement.setInt(1, CorrelationAttributeInstance.IMEI_TYPE_ID);
3877 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3878 preparedStatement.setString(3, imeiNumberDbTableName);
3879 preparedStatement.setInt(4, 1);
3880 preparedStatement.setInt(5, 1);
3881 preparedStatement.execute();
3884 preparedStatement = conn.prepareStatement(addAttributeSql);
3885 preparedStatement.setInt(1, CorrelationAttributeInstance.IMSI_TYPE_ID);
3886 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3887 preparedStatement.setString(3, imsiNumberDbTableName);
3888 preparedStatement.setInt(4, 1);
3889 preparedStatement.setInt(5, 1);
3890 preparedStatement.execute();
3893 preparedStatement = conn.prepareStatement(addAttributeSql);
3894 preparedStatement.setInt(1, CorrelationAttributeInstance.ICCID_TYPE_ID);
3895 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3896 preparedStatement.setString(3, iccidNumberDbTableName);
3897 preparedStatement.setInt(4, 1);
3898 preparedStatement.setInt(5, 1);
3899 preparedStatement.execute();
3902 for (String tableName : instaceTablesToAdd) {
3903 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3904 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3905 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3906 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3907 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3911 String instance_type_dbname;
3912 final String objectIdColumnName =
"file_obj_id";
3913 for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
3914 instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
3915 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3916 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3918 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3924 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3925 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3927 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3928 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3930 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3931 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3942 String creationMajorVer;
3943 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3944 if (resultSet.next()) {
3945 creationMajorVer = resultSet.getString(
"value");
3947 creationMajorVer =
"0";
3949 String creationMinorVer;
3950 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3951 if (resultSet.next()) {
3952 creationMinorVer = resultSet.getString(
"value");
3954 creationMinorVer =
"0";
3956 statement.execute(
"DROP TABLE db_info");
3957 if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) {
3958 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3960 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3962 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3963 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3964 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3965 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
3970 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
3971 switch (selectedPlatform) {
3973 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
3975 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
3979 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
3980 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
3981 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
3983 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
3984 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
3985 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
3986 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
3987 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
3988 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesNameIndexStatement());
3989 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesObjectIdIndexStatement());
3990 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
3991 statement.execute(
"DROP TABLE old_data_sources");
3994 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3999 (
new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
4002 (
new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);
4004 updateSchemaVersion(conn);
4006 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
4007 }
catch (SQLException | CentralRepoException ex) {
4012 }
catch (SQLException ex2) {
4013 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
4017 CentralRepoDbUtil.closeResultSet(resultSet);
4018 CentralRepoDbUtil.closeStatement(preparedStatement);
4019 CentralRepoDbUtil.closeStatement(statement);
4020 CentralRepoDbUtil.closeConnection(conn);
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)