Autopsy  4.9.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SqliteEamDb.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2015-2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.centralrepository.datamodel;
20 
21 import java.sql.Connection;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.concurrent.locks.ReentrantReadWriteLock;
29 import java.util.logging.Level;
30 import org.apache.commons.dbcp2.BasicDataSource;
32 import org.sleuthkit.datamodel.TskData;
35 
41 final class SqliteEamDb extends AbstractSqlEamDb {
42 
43  private final static Logger LOGGER = Logger.getLogger(SqliteEamDb.class.getName());
44 
45  private static SqliteEamDb instance;
46 
47  private BasicDataSource connectionPool = null;
48 
49  private final SqliteEamDbSettings dbSettings;
50 
51  // While the Sqlite database should only be used for single users, it is still
52  // possible for multiple threads to attempt to write to the database simultaneously.
53  private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);
54 
63  public synchronized static SqliteEamDb getInstance() throws EamDbException {
64  if (instance == null) {
65  instance = new SqliteEamDb();
66  }
67 
68  return instance;
69  }
70 
77  private SqliteEamDb() throws EamDbException {
78  dbSettings = new SqliteEamDbSettings();
79  bulkArtifactsThreshold = dbSettings.getBulkThreshold();
80  }
81 
82  @Override
83  public void shutdownConnections() throws EamDbException {
84  try {
85  synchronized (this) {
86  if (null != connectionPool) {
87  connectionPool.close();
88  connectionPool = null; // force it to be re-created on next connect()
89  }
90  clearCaches();
91  }
92  } catch (SQLException ex) {
93  throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS
94  }
95  }
96 
97  @Override
98  public void updateSettings() {
99  synchronized (this) {
100  dbSettings.loadSettings();
101  bulkArtifactsThreshold = dbSettings.getBulkThreshold();
102  }
103  }
104 
105  @Override
106  public void saveSettings() {
107  synchronized (this) {
108  dbSettings.saveSettings();
109  }
110  }
111 
112  @Override
113  public void reset() throws EamDbException {
114  try {
115  acquireExclusiveLock();
116 
117  Connection conn = connect();
118 
119  try {
120 
121  Statement dropContent = conn.createStatement();
122  dropContent.executeUpdate("DELETE FROM organizations");
123  dropContent.executeUpdate("DELETE FROM cases");
124  dropContent.executeUpdate("DELETE FROM data_sources");
125  dropContent.executeUpdate("DELETE FROM reference_sets");
126  dropContent.executeUpdate("DELETE FROM artifact_types");
127  dropContent.executeUpdate("DELETE FROM db_info");
128 
129  String instancesTemplate = "DELETE FROM %s_instances";
130  String referencesTemplate = "DELETE FROM global_files";
131  for (CorrelationAttributeInstance.Type type : defaultCorrelationTypes) {
132  dropContent.executeUpdate(String.format(instancesTemplate, type.getDbTableName()));
133  // FUTURE: support other reference types
134  if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
135  dropContent.executeUpdate(String.format(referencesTemplate, type.getDbTableName()));
136  }
137  }
138 
139  dropContent.executeUpdate("VACUUM");
140  } catch (SQLException ex) {
141  LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
142  } finally {
143  EamDbUtil.closeConnection(conn);
144  }
145 
146  dbSettings.insertDefaultDatabaseContent();
147  } finally {
148  releaseExclusiveLock();
149  }
150  }
151 
156  private void setupConnectionPool() throws EamDbException {
157 
158  if (dbSettings.dbFileExists() == false) {
159  throw new EamDbException("Central repository database missing");
160  }
161 
162  connectionPool = new BasicDataSource();
163  connectionPool.setDriverClassName(dbSettings.getDriver());
164  connectionPool.setUrl(dbSettings.getConnectionURL());
165 
166  // tweak pool configuration
167  connectionPool.setInitialSize(50);
168  connectionPool.setMaxTotal(-1);
169  connectionPool.setMaxIdle(-1);
170  connectionPool.setMaxWaitMillis(1000);
171  connectionPool.setValidationQuery(dbSettings.getValidationQuery());
172  connectionPool.setConnectionInitSqls(Arrays.asList("PRAGMA foreign_keys = ON"));
173  }
174 
182  @Override
183  protected Connection connect() throws EamDbException {
184  synchronized (this) {
185  if (!EamDb.isEnabled()) {
186  throw new EamDbException("Central Repository module is not enabled"); // NON-NLS
187  }
188 
189  if (connectionPool == null) {
190  setupConnectionPool();
191  }
192 
193  try {
194  return connectionPool.getConnection();
195  } catch (SQLException ex) {
196  throw new EamDbException("Error getting connection from connection pool.", ex); // NON-NLS
197  }
198  }
199  }
200 
201  @Override
202  protected String getConflictClause() {
203  // For sqlite, our conflict clause is part of the table schema
204  return "";
205  }
206 
215  @Override
216  public void newDbInfo(String name, String value) throws EamDbException {
217  try {
218  acquireExclusiveLock();
219  super.newDbInfo(name, value);
220  } finally {
221  releaseExclusiveLock();
222  }
223  }
224 
234  @Override
235  public String getDbInfo(String name) throws EamDbException {
236  try {
237  acquireSharedLock();
238  return super.getDbInfo(name);
239  } finally {
240  releaseSharedLock();
241  }
242  }
243 
252  @Override
253  public void updateDbInfo(String name, String value) throws EamDbException {
254  try {
255  acquireExclusiveLock();
256  super.updateDbInfo(name, value);
257  } finally {
258  releaseExclusiveLock();
259  }
260  }
261 
267  @Override
268  public CorrelationCase newCase(Case autopsyCase) throws EamDbException {
269  try {
270  acquireExclusiveLock();
271  return super.newCase(autopsyCase);
272  } finally {
273  releaseExclusiveLock();
274  }
275  }
276 
277  @Override
278  public void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException{
279  try {
280  acquireExclusiveLock();
281  super.addDataSourceObjectId(rowId, dataSourceObjectId);
282  } finally {
283  releaseExclusiveLock();
284  }
285  }
286 
294  @Override
295  public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
296  try {
297  acquireExclusiveLock();
298  return super.newCase(eamCase);
299  } finally {
300  releaseExclusiveLock();
301  }
302  }
303 
309  @Override
310  public void updateCase(CorrelationCase eamCase) throws EamDbException {
311  try {
312  acquireExclusiveLock();
313  super.updateCase(eamCase);
314  } finally {
315  releaseExclusiveLock();
316  }
317  }
318 
326  @Override
327  public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
328  try {
329  acquireSharedLock();
330  return super.getCaseByUUID(caseUUID);
331  } finally {
332  releaseSharedLock();
333  }
334  }
335 
343  @Override
344  public CorrelationCase getCaseById(int caseId) throws EamDbException {
345  try {
346  acquireSharedLock();
347  return super.getCaseById(caseId);
348  } finally {
349  releaseSharedLock();
350  }
351 
352  }
353 
359  @Override
360  public List<CorrelationCase> getCases() throws EamDbException {
361  try {
362  acquireSharedLock();
363  return super.getCases();
364  } finally {
365  releaseSharedLock();
366  }
367  }
368 
374  @Override
375  public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
376  try {
377  acquireExclusiveLock();
378  return super.newDataSource(eamDataSource);
379  } finally {
380  releaseExclusiveLock();
381  }
382  }
383 
393  @Override
394  public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException {
395  try {
396  acquireSharedLock();
397  return super.getDataSource(correlationCase, caseDbDataSourceId);
398  } finally {
399  releaseSharedLock();
400  }
401  }
402 
412  @Override
413  public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase, int dataSourceId) throws EamDbException {
414  try {
415  acquireSharedLock();
416  return super.getDataSourceById(correlationCase, dataSourceId);
417  } finally {
418  releaseSharedLock();
419  }
420  }
421 
427  @Override
428  public List<CorrelationDataSource> getDataSources() throws EamDbException {
429  try {
430  acquireSharedLock();
431  return super.getDataSources();
432  } finally {
433  releaseSharedLock();
434  }
435  }
436 
443  @Override
444  public void addArtifactInstance(CorrelationAttributeInstance eamArtifact) throws EamDbException {
445  try {
446  acquireExclusiveLock();
447  super.addArtifactInstance(eamArtifact);
448  } finally {
449  releaseExclusiveLock();
450  }
451  }
452 
462  @Override
463  public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
464  try {
465  acquireSharedLock();
466  return super.getArtifactInstancesByTypeValue(aType, value);
467  } finally {
468  releaseSharedLock();
469  }
470  }
471 
483  @Override
484  public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttributeInstance.Type aType, String filePath) throws EamDbException {
485  try {
486  acquireSharedLock();
487  return super.getArtifactInstancesByPath(aType, filePath);
488  } finally {
489  releaseSharedLock();
490  }
491  }
492 
505  @Override
506  public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
507  try {
508  acquireSharedLock();
509  return super.getCountArtifactInstancesByTypeValue(aType, value);
510  } finally {
511  releaseSharedLock();
512  }
513  }
514 
515  @Override
516  public int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException, CorrelationAttributeNormalizationException {
517  try {
518  acquireSharedLock();
519  return super.getFrequencyPercentage(corAttr);
520  } finally {
521  releaseSharedLock();
522  }
523  }
524 
537  @Override
538  public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
539  try {
540  acquireSharedLock();
541  return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
542  } finally {
543  releaseSharedLock();
544  }
545  }
546 
547  @Override
548  public Long getCountUniqueDataSources() throws EamDbException {
549  try {
550  acquireSharedLock();
551  return super.getCountUniqueDataSources();
552  } finally {
553  releaseSharedLock();
554  }
555  }
556 
568  @Override
569  public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource) throws EamDbException {
570  try {
571  acquireSharedLock();
572  return super.getCountArtifactInstancesByCaseDataSource(correlationDataSource);
573  } finally {
574  releaseSharedLock();
575  }
576  }
577 
582  @Override
583  public void commitAttributeInstancesBulk() throws EamDbException {
584  try {
585  acquireExclusiveLock();
586  super.commitAttributeInstancesBulk();
587  } finally {
588  releaseExclusiveLock();
589  }
590  }
591 
595  @Override
596  public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
597  try {
598  acquireExclusiveLock();
599  super.bulkInsertCases(cases);
600  } finally {
601  releaseExclusiveLock();
602  }
603  }
604 
615  @Override
616  public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
617  try {
618  acquireExclusiveLock();
619  super.setAttributeInstanceKnownStatus(eamArtifact, knownStatus);
620  } finally {
621  releaseExclusiveLock();
622  }
623  }
624 
634  @Override
635  public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
636  try {
637  acquireSharedLock();
638  return super.getArtifactInstancesKnownBad(aType, value);
639  } finally {
640  releaseSharedLock();
641  }
642  }
643 
655  @Override
656  public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType) throws EamDbException {
657  try {
658  acquireSharedLock();
659  return super.getArtifactInstancesKnownBad(aType);
660  } finally {
661  releaseSharedLock();
662  }
663  }
664 
673  @Override
674  public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
675  try {
676  acquireSharedLock();
677  return super.getCountArtifactInstancesKnownBad(aType, value);
678  } finally {
679  releaseSharedLock();
680  }
681  }
682 
695  @Override
696  public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
697  try {
698  acquireSharedLock();
699  return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
700  } finally {
701  releaseSharedLock();
702  }
703  }
704 
712  @Override
713  public void deleteReferenceSet(int referenceSetID) throws EamDbException {
714  try {
715  acquireExclusiveLock();
716  super.deleteReferenceSet(referenceSetID);
717  } finally {
718  releaseExclusiveLock();
719  }
720  }
721 
731  @Override
732  public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException, CorrelationAttributeNormalizationException {
733  try {
734  acquireSharedLock();
735  return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID);
736  } finally {
737  releaseSharedLock();
738  }
739  }
740 
749  @Override
750  public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException {
751  try {
752  acquireSharedLock();
753  super.processInstanceTable(type, instanceTableCallback);
754  } finally {
755  releaseSharedLock();
756  }
757  }
758 
767  @Override
768  public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException {
769  try {
770  acquireSharedLock();
771  super.processInstanceTableWhere(type, whereClause, instanceTableCallback);
772  } finally {
773  releaseSharedLock();
774  }
775  }
776 
789  @Override
790  public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException {
791  try {
792  acquireSharedLock();
793  return super.referenceSetExists(referenceSetName, version);
794  } finally {
795  releaseSharedLock();
796  }
797  }
798 
807  @Override
808  public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
809  try {
810  acquireSharedLock();
811  return super.isArtifactKnownBadByReference(aType, value);
812  } finally {
813  releaseSharedLock();
814  }
815  }
816 
826  @Override
827  public EamOrganization newOrganization(EamOrganization eamOrg) throws EamDbException {
828  try {
829  acquireExclusiveLock();
830  return super.newOrganization(eamOrg);
831  } finally {
832  releaseExclusiveLock();
833  }
834  }
835 
843  @Override
844  public List<EamOrganization> getOrganizations() throws EamDbException {
845  try {
846  acquireSharedLock();
847  return super.getOrganizations();
848  } finally {
849  releaseSharedLock();
850  }
851  }
852 
862  @Override
863  public EamOrganization getOrganizationByID(int orgID) throws EamDbException {
864  try {
865  acquireSharedLock();
866  return super.getOrganizationByID(orgID);
867  } finally {
868  releaseSharedLock();
869  }
870  }
871 
872  @Override
873  public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
874  try {
875  acquireExclusiveLock();
876  super.updateOrganization(updatedOrganization);
877  } finally {
878  releaseExclusiveLock();
879  }
880  }
881 
882  @Override
883  public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
884  try {
885  acquireExclusiveLock();
886  super.deleteOrganization(organizationToDelete);
887  } finally {
888  releaseExclusiveLock();
889  }
890  }
891 
901  @Override
902  public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
903  try {
904  acquireExclusiveLock();
905  return super.newReferenceSet(eamGlobalSet);
906  } finally {
907  releaseExclusiveLock();
908  }
909  }
910 
920  @Override
921  public EamGlobalSet getReferenceSetByID(int referenceSetID) throws EamDbException {
922  try {
923  acquireSharedLock();
924  return super.getReferenceSetByID(referenceSetID);
925  } finally {
926  releaseSharedLock();
927  }
928  }
929 
939  @Override
940  public List<EamGlobalSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws EamDbException {
941  try {
942  acquireSharedLock();
943  return super.getAllReferenceSets(correlationType);
944  } finally {
945  releaseSharedLock();
946  }
947  }
948 
958  @Override
959  public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws EamDbException {
960  try {
961  acquireExclusiveLock();
962  super.addReferenceInstance(eamGlobalFileInstance, correlationType);
963  } finally {
964  releaseExclusiveLock();
965  }
966  }
967 
973  @Override
974  public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws EamDbException {
975  try {
976  acquireExclusiveLock();
977  super.bulkInsertReferenceTypeEntries(globalInstances, contentType);
978  } finally {
979  releaseExclusiveLock();
980  }
981  }
982 
993  @Override
994  public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException, CorrelationAttributeNormalizationException {
995  try {
996  acquireSharedLock();
997  return super.getReferenceInstancesByTypeValue(aType, aValue);
998  } finally {
999  releaseSharedLock();
1000  }
1001  }
1002 
1012  @Override
1013  public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws EamDbException {
1014  try {
1015  acquireExclusiveLock();
1016  return super.newCorrelationType(newType);
1017  } finally {
1018  releaseExclusiveLock();
1019  }
1020  }
1021 
1031  @Override
1032  public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws EamDbException {
1033  try {
1034  acquireSharedLock();
1035  return super.getDefinedCorrelationTypes();
1036  } finally {
1037  releaseSharedLock();
1038  }
1039  }
1040 
1050  @Override
1051  public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws EamDbException {
1052  try {
1053  acquireSharedLock();
1054  return super.getEnabledCorrelationTypes();
1055  } finally {
1056  releaseSharedLock();
1057  }
1058  }
1059 
1069  @Override
1070  public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws EamDbException {
1071  try {
1072  acquireSharedLock();
1073  return super.getSupportedCorrelationTypes();
1074  } finally {
1075  releaseSharedLock();
1076  }
1077  }
1078 
1086  @Override
1087  public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws EamDbException {
1088  try {
1089  acquireExclusiveLock();
1090  super.updateCorrelationType(aType);
1091  } finally {
1092  releaseExclusiveLock();
1093  }
1094  }
1095 
1105  @Override
1106  public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws EamDbException {
1107  try {
1108  acquireSharedLock();
1109  return super.getCorrelationTypeById(typeId);
1110  } finally {
1111  releaseSharedLock();
1112  }
1113  }
1114 
1120  @Override
1121  public void upgradeSchema() throws EamDbException, SQLException {
1122  try {
1123  acquireExclusiveLock();
1124  super.upgradeSchema();
1125  } finally {
1126  releaseExclusiveLock();
1127  }
1128  }
1129 
1141  @Override
1142  public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException {
1143  // Multiple users are not supported for SQLite
1144  return null;
1145  }
1146 
1152  private void acquireExclusiveLock() {
1153  rwLock.writeLock().lock();
1154  }
1155 
1161  private void releaseExclusiveLock() {
1162  rwLock.writeLock().unlock();
1163  }
1164 
1170  private void acquireSharedLock() {
1171  rwLock.readLock().lock();
1172  }
1173 
1179  private void releaseSharedLock() {
1180  rwLock.readLock().unlock();
1181  }
1182 
1183  @Override
1184  boolean doesColumnExist(Connection conn, String tableName, String columnName) throws SQLException {
1185  final String tableInfoQueryTemplate = "PRAGMA table_info(%s)"; //NON-NLS
1186  ResultSet resultSet = null;
1187  Statement statement = null;
1188  boolean columnExists = false;
1189  try {
1190  statement = conn.createStatement();
1191  resultSet = statement.executeQuery(String.format(tableInfoQueryTemplate, tableName));
1192  while (resultSet.next()) {
1193  // the second value ( 2 ) is the column name
1194  if (resultSet.getString(2).equals(columnName)) {
1195  columnExists = true;
1196  break;
1197  }
1198  }
1199  } finally {
1200  EamDbUtil.closeResultSet(resultSet);
1201  EamDbUtil.closeStatement(statement);
1202  }
1203  return columnExists;
1204  }
1205 }

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.