Autopsy  4.20.0
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;
36 
44 
45  public final static String DEFAULT_DBNAME = CentralRepoSettings.getInstance().getDefaultDbName(); // NON-NLS
46  private final static Logger LOGGER = Logger.getLogger(SqliteCentralRepoSettings.class.getName());
47  private final Path userConfigDir = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath());
49 
50  //property names
52  private static final String DATABASE_NAME = CentralRepoSettings.getInstance().getDatabaseNameKey(); //NON-NLS
53  private static final String DATABASE_PATH = CentralRepoSettings.getInstance().getDatabasePathKey(); //NON-NLS
54  private static final String BULK_THRESHOLD = "db.sqlite.bulkThreshold"; //NON-NLS
55 
56  private final static String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS
57  private final static String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
58  private final static String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
59 
60  private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*(\\.db)?";
61  private String dbName;
62  private String dbDirectory;
63  private int bulkThreshold;
64 
66  loadSettings();
67  }
68 
69  public void loadSettings() {
70  dbName = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_NAME); // NON-NLS
71  if (dbName == null || dbName.isEmpty()) {
72  dbName = DEFAULT_DBNAME;
73  }
74 
75  dbDirectory = readDbPath(); // NON-NLS
76  if (dbDirectory == null || dbDirectory.isEmpty()) {
77  dbDirectory = DEFAULT_DBDIRECTORY;
78  }
79 
80  try {
81  String bulkThresholdString = ModuleSettings.getConfigSetting(PROFILE_NAME, BULK_THRESHOLD); // NON-NLS
82  if (bulkThresholdString == null || bulkThresholdString.isEmpty()) {
83  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
84  } else {
85  this.bulkThreshold = Integer.parseInt(bulkThresholdString);
86  if (getBulkThreshold() <= 0) {
87  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
88  }
89  }
90  } catch (NumberFormatException ex) {
91  this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD;
92  }
93  }
94 
95  public String toString() {
96  return String.format("SqliteCentralRepoSettings: [db type: sqlite, directory: %s, name: %s]", getDbDirectory(), getDbName());
97  }
98 
102  public void setupDefaultSettings() {
103  dbName = DEFAULT_DBNAME;
104  dbDirectory = DEFAULT_DBDIRECTORY;
105  }
106 
107  public void saveSettings() {
109 
110  ModuleSettings.setConfigSetting(PROFILE_NAME, DATABASE_NAME, getDbName()); // NON-NLS
111  saveDbPath(getDbDirectory()); // NON-NLS
112  ModuleSettings.setConfigSetting(PROFILE_NAME, BULK_THRESHOLD, Integer.toString(getBulkThreshold())); // NON-NLS
113  }
114 
123  private void saveDbPath(String fullPath) {
124  Path relativePath = Paths.get(fullPath);
125  // check if the path is within user directory
126  if (Paths.get(fullPath).startsWith(userConfigDir)) {
127  // relativize the path
128  relativePath = userConfigDir.relativize(relativePath);
129  }
130  // Use properties to persist the logo to use.
131  ModuleSettings.setConfigSetting(PROFILE_NAME, DATABASE_PATH, relativePath.toString());
132  }
133 
142  private String readDbPath() {
143 
144  String curPath = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_PATH);
145 
146 
147  //if has been set, validate it's correct, if not set, return null
148  if (curPath != null && !curPath.isEmpty()) {
149 
150  // check if the path is an absolute path (starts with either drive letter or "/")
151  Path driveLetterOrNetwork = Paths.get(curPath).getRoot();
152  if (driveLetterOrNetwork != null) {
153  // absolute path
154  return curPath;
155  }
156 
157  // Path is a relative path. Reverse path relativization performed in saveDbPath()
158  Path absolutePath = userConfigDir.resolve(curPath);
159  curPath = absolutePath.toString();
160  if (new File(curPath).canRead() == false) {
161  //use default
162  LOGGER.log(Level.INFO, "Path to SQLite Central Repository database is not valid: {0}", curPath); //NON-NLS
163  curPath = null;
164  }
165  }
166 
167  return curPath;
168  }
169 
175  public boolean dbFileExists() {
176  File dbFile = new File(getFileNameWithPath());
177  if (!dbFile.exists()) {
178  return false;
179  }
180  // It's unlikely, but make sure the file isn't actually a directory
181  return (!dbFile.isDirectory());
182  }
183 
184  @Override
185  public boolean verifyDatabaseExists() {
186  return dbDirectoryExists();
187  }
188 
194  public boolean dbDirectoryExists() {
195  // Ensure dbDirectory is a valid directory
196  File dbDir = new File(getDbDirectory());
197 
198  if (!dbDir.exists()) {
199  return false;
200  } else if (!dbDir.isDirectory()) {
201  return false;
202  }
203 
204  return true;
205 
206  }
207 
213  @Override
214  public boolean createDatabase() {
215  return createDbDirectory();
216  }
217 
223  public boolean createDbDirectory() {
224  if (!dbDirectoryExists()) {
225  try {
226  File dbDir = new File(getDbDirectory());
227  Files.createDirectories(dbDir.toPath());
228  LOGGER.log(Level.INFO, "sqlite directory did not exist, created it at {0}.", getDbDirectory()); // NON-NLS
229  } catch (IOException | InvalidPathException | SecurityException ex) {
230  LOGGER.log(Level.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS
231  return false;
232  }
233  }
234 
235  return true;
236  }
237 
243  public boolean deleteDatabase() {
244  File dbFile = new File(this.getFileNameWithPath());
245  return dbFile.delete();
246  }
247 
253  String getConnectionURL() {
254  StringBuilder url = new StringBuilder();
255  url.append(getJDBCBaseURI());
256  url.append(getFileNameWithPath());
257 
258  return url.toString();
259  }
260 
269  Connection getEphemeralConnection() {
270  if (!dbDirectoryExists()) {
271  return null;
272  }
273 
274  Connection conn;
275  try {
276  String url = getConnectionURL();
277  Class.forName(getDriver());
278  conn = DriverManager.getConnection(url);
279  } catch (ClassNotFoundException | SQLException ex) {
280  LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS
281  conn = null;
282  }
283  return conn;
284  }
285 
292  public boolean verifyConnection() {
293  Connection conn = getEphemeralConnection();
294  if (null == conn) {
295  return false;
296  }
297 
298  boolean result = CentralRepoDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
300  return result;
301  }
302 
309  public boolean verifyDatabaseSchema() {
310  Connection conn = getEphemeralConnection();
311  if (null == conn) {
312  return false;
313  }
314 
315  boolean result = CentralRepoDbUtil.schemaVersionIsSet(conn);
317  return result;
318  }
319 
320  boolean isChanged() {
321  String dbNameString = ModuleSettings.getConfigSetting(PROFILE_NAME, DATABASE_NAME); // NON-NLS
322  String dbDirectoryString = readDbPath(); // NON-NLS
323  String bulkThresholdString = ModuleSettings.getConfigSetting(PROFILE_NAME, BULK_THRESHOLD); // NON-NLS
324 
325  return !dbName.equals(dbNameString)
326  || !dbDirectory.equals(dbDirectoryString)
327  || !Integer.toString(bulkThreshold).equals(bulkThresholdString);
328  }
329 
333  public String getDbName() {
334  return dbName;
335  }
336 
342  public void setDbName(String dbName) throws CentralRepoException {
343  if (dbName == null || dbName.isEmpty()) {
344  throw new CentralRepoException("Invalid database file name. Cannot be null or empty."); // NON-NLS
345  } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
346  throw new CentralRepoException("Invalid database file name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'."); // NON-NLS
347  }
348 
349  this.dbName = dbName;
350  }
351 
355  int getBulkThreshold() {
356  return bulkThreshold;
357  }
358 
362  void setBulkThreshold(int bulkThreshold) throws CentralRepoException {
363  if (bulkThreshold > 0) {
364  this.bulkThreshold = bulkThreshold;
365  } else {
366  throw new CentralRepoException("Invalid bulk threshold."); // NON-NLS
367  }
368  }
369 
373  public String getDbDirectory() {
374  return dbDirectory;
375  }
376 
384  public void setDbDirectory(String dbDirectory) throws CentralRepoException {
385  if (dbDirectory != null && !dbDirectory.isEmpty()) {
386  this.dbDirectory = dbDirectory;
387  } else {
388  throw new CentralRepoException("Invalid directory for sqlite database. Cannot empty"); // NON-NLS
389  }
390  }
391 
397  public String getFileNameWithPath() {
398  return getDbDirectory() + File.separator + getDbName();
399  }
400 
404  String getDriver() {
405  return JDBC_DRIVER;
406  }
407 
411  String getValidationQuery() {
412  return VALIDATION_QUERY;
413  }
414 
418  String getJDBCBaseURI() {
419  return JDBC_BASE_URI;
420  }
421 
422  @Override
424  if (dbFileExists()) {
425  if (verifyConnection()) {
426  if (verifyDatabaseSchema()) {
428  } else {
430  }
431  } else {
433  }
434  } else {
436  }
437  }
438 }
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-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.