Autopsy  4.19.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SqliteCentralRepoSettings.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2015-2020 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.io.File;
22 import java.io.IOException;
23 import java.nio.file.Files;
24 import java.nio.file.InvalidPathException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.sql.Connection;
28 import java.sql.DriverManager;
29 import java.sql.SQLException;
30 import java.util.logging.Level;
31 import java.util.regex.Pattern;
35 
43 
44  public final static String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS
45  private final static Logger LOGGER = Logger.getLogger(SqliteCentralRepoSettings.class.getName());
46  private final Path userConfigDir = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath());
47  private final static String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "central_repository"; // NON-NLS
48 
49  //property names
50  private static final String PROFILE_NAME = "CentralRepository";
51  private static final String DATABASE_NAME = "db.sqlite.dbName"; //NON-NLS
52  private static final String DATABASE_PATH = "db.sqlite.dbDirectory"; //NON-NLS
53  private static final String BULK_THRESHOLD = "db.sqlite.bulkThreshold"; //NON-NLS
54 
55  private final static String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS
56  private final static String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
57  private final static String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
58 
59  private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*(\\.db)?";
60  private String dbName;
61  private String dbDirectory;
62  private int bulkThreshold;
63 
65  loadSettings();
66  }
67 
68  public void loadSettings() {
69  dbName = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_NAME); // NON-NLS
70  if (dbName == null || dbName.isEmpty()) {
71  dbName = DEFAULT_DBNAME;
72  }
73 
74  dbDirectory = readDbPath(); // NON-NLS
75  if (dbDirectory == null || dbDirectory.isEmpty()) {
76  dbDirectory = DEFAULT_DBDIRECTORY;
77  }
78 
79  try {
80  String bulkThresholdString = ModuleSettings.getConfigSetting(PROFILE_NAME, BULK_THRESHOLD); // NON-NLS
81  if (bulkThresholdString == null || bulkThresholdString.isEmpty()) {
82  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
83  } else {
84  this.bulkThreshold = Integer.parseInt(bulkThresholdString);
85  if (getBulkThreshold() <= 0) {
86  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
87  }
88  }
89  } catch (NumberFormatException ex) {
90  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
91  }
92  }
93 
94  public String toString() {
95  return String.format("SqliteCentralRepoSettings: [db type: sqlite, directory: %s, name: %s]", getDbDirectory(), getDbName());
96  }
97 
101  public void setupDefaultSettings() {
102  dbName = DEFAULT_DBNAME;
103  dbDirectory = DEFAULT_DBDIRECTORY;
104  }
105 
106  public void saveSettings() {
108 
109  ModuleSettings.setConfigSetting(PROFILE_NAME, DATABASE_NAME, getDbName()); // NON-NLS
110  saveDbPath(getDbDirectory()); // NON-NLS
111  ModuleSettings.setConfigSetting(PROFILE_NAME, BULK_THRESHOLD, Integer.toString(getBulkThreshold())); // NON-NLS
112  }
113 
122  private void saveDbPath(String fullPath) {
123  Path relativePath = Paths.get(fullPath);
124  // check if the path is within user directory
125  if (Paths.get(fullPath).startsWith(userConfigDir)) {
126  // relativize the path
127  relativePath = userConfigDir.relativize(relativePath);
128  }
129  // Use properties to persist the logo to use.
130  ModuleSettings.setConfigSetting(PROFILE_NAME, DATABASE_PATH, relativePath.toString());
131  }
132 
141  private String readDbPath() {
142 
143  String curPath = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_PATH);
144 
145 
146  //if has been set, validate it's correct, if not set, return null
147  if (curPath != null && !curPath.isEmpty()) {
148 
149  // check if the path is an absolute path (starts with either drive letter or "/")
150  Path driveLetterOrNetwork = Paths.get(curPath).getRoot();
151  if (driveLetterOrNetwork != null) {
152  // absolute path
153  return curPath;
154  }
155 
156  // Path is a relative path. Reverse path relativization performed in saveDbPath()
157  Path absolutePath = userConfigDir.resolve(curPath);
158  curPath = absolutePath.toString();
159  if (new File(curPath).canRead() == false) {
160  //use default
161  LOGGER.log(Level.INFO, "Path to SQLite Central Repository database is not valid: {0}", curPath); //NON-NLS
162  curPath = null;
163  }
164  }
165 
166  return curPath;
167  }
168 
174  public boolean dbFileExists() {
175  File dbFile = new File(getFileNameWithPath());
176  if (!dbFile.exists()) {
177  return false;
178  }
179  // It's unlikely, but make sure the file isn't actually a directory
180  return (!dbFile.isDirectory());
181  }
182 
183  @Override
184  public boolean verifyDatabaseExists() {
185  return dbDirectoryExists();
186  }
187 
193  public boolean dbDirectoryExists() {
194  // Ensure dbDirectory is a valid directory
195  File dbDir = new File(getDbDirectory());
196 
197  if (!dbDir.exists()) {
198  return false;
199  } else if (!dbDir.isDirectory()) {
200  return false;
201  }
202 
203  return true;
204 
205  }
206 
212  @Override
213  public boolean createDatabase() {
214  return createDbDirectory();
215  }
216 
222  public boolean createDbDirectory() {
223  if (!dbDirectoryExists()) {
224  try {
225  File dbDir = new File(getDbDirectory());
226  Files.createDirectories(dbDir.toPath());
227  LOGGER.log(Level.INFO, "sqlite directory did not exist, created it at {0}.", getDbDirectory()); // NON-NLS
228  } catch (IOException | InvalidPathException | SecurityException ex) {
229  LOGGER.log(Level.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS
230  return false;
231  }
232  }
233 
234  return true;
235  }
236 
242  public boolean deleteDatabase() {
243  File dbFile = new File(this.getFileNameWithPath());
244  return dbFile.delete();
245  }
246 
252  String getConnectionURL() {
253  StringBuilder url = new StringBuilder();
254  url.append(getJDBCBaseURI());
255  url.append(getFileNameWithPath());
256 
257  return url.toString();
258  }
259 
268  Connection getEphemeralConnection() {
269  if (!dbDirectoryExists()) {
270  return null;
271  }
272 
273  Connection conn;
274  try {
275  String url = getConnectionURL();
276  Class.forName(getDriver());
277  conn = DriverManager.getConnection(url);
278  } catch (ClassNotFoundException | SQLException ex) {
279  LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS
280  conn = null;
281  }
282  return conn;
283  }
284 
291  public boolean verifyConnection() {
292  Connection conn = getEphemeralConnection();
293  if (null == conn) {
294  return false;
295  }
296 
297  boolean result = CentralRepoDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
299  return result;
300  }
301 
308  public boolean verifyDatabaseSchema() {
309  Connection conn = getEphemeralConnection();
310  if (null == conn) {
311  return false;
312  }
313 
314  boolean result = CentralRepoDbUtil.schemaVersionIsSet(conn);
316  return result;
317  }
318 
319  boolean isChanged() {
320  String dbNameString = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_NAME); // NON-NLS
321  String dbDirectoryString = readDbPath(); // NON-NLS
322  String bulkThresholdString = ModuleSettings.getConfigSetting(PROFILE_NAME, BULK_THRESHOLD); // NON-NLS
323 
324  return !dbName.equals(dbNameString)
325  || !dbDirectory.equals(dbDirectoryString)
326  || !Integer.toString(bulkThreshold).equals(bulkThresholdString);
327  }
328 
332  public String getDbName() {
333  return dbName;
334  }
335 
341  public void setDbName(String dbName) throws CentralRepoException {
342  if (dbName == null || dbName.isEmpty()) {
343  throw new CentralRepoException("Invalid database file name. Cannot be null or empty."); // NON-NLS
344  } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
345  throw new CentralRepoException("Invalid database file name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'."); // NON-NLS
346  }
347 
348  this.dbName = dbName;
349  }
350 
354  int getBulkThreshold() {
355  return bulkThreshold;
356  }
357 
361  void setBulkThreshold(int bulkThreshold) throws CentralRepoException {
362  if (bulkThreshold > 0) {
363  this.bulkThreshold = bulkThreshold;
364  } else {
365  throw new CentralRepoException("Invalid bulk threshold."); // NON-NLS
366  }
367  }
368 
372  public String getDbDirectory() {
373  return dbDirectory;
374  }
375 
383  public void setDbDirectory(String dbDirectory) throws CentralRepoException {
384  if (dbDirectory != null && !dbDirectory.isEmpty()) {
385  this.dbDirectory = dbDirectory;
386  } else {
387  throw new CentralRepoException("Invalid directory for sqlite database. Cannot empty"); // NON-NLS
388  }
389  }
390 
396  public String getFileNameWithPath() {
397  return getDbDirectory() + File.separator + getDbName();
398  }
399 
403  String getDriver() {
404  return JDBC_DRIVER;
405  }
406 
410  String getValidationQuery() {
411  return VALIDATION_QUERY;
412  }
413 
417  String getJDBCBaseURI() {
418  return JDBC_BASE_URI;
419  }
420 
421  @Override
423  if (dbFileExists()) {
424  if (verifyConnection()) {
425  if (verifyDatabaseSchema()) {
427  } else {
429  }
430  } else {
432  }
433  } else {
435  }
436  }
437 }
static synchronized String getConfigSetting(String moduleName, String settingName)
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
static boolean executeValidationQuery(Connection conn, String validationQuery)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2021 Basis Technology. Generated on: Thu Sep 30 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.