Autopsy 4.22.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 */
19package org.sleuthkit.autopsy.centralrepository.datamodel;
20
21import java.io.File;
22import java.io.IOException;
23import java.nio.file.Files;
24import java.nio.file.InvalidPathException;
25import java.nio.file.Path;
26import java.nio.file.Paths;
27import java.sql.Connection;
28import java.sql.DriverManager;
29import java.sql.SQLException;
30import java.util.logging.Level;
31import java.util.regex.Pattern;
32import org.sleuthkit.autopsy.centralrepository.CentralRepoSettings;
33import org.sleuthkit.autopsy.coreutils.Logger;
34import org.sleuthkit.autopsy.coreutils.ModuleSettings;
35import org.sleuthkit.autopsy.coreutils.PlatformUtil;
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
68
69 public void loadSettings() {
71 if (dbName == null || dbName.isEmpty()) {
73 }
74
75 dbDirectory = readDbPath(); // NON-NLS
76 if (dbDirectory == null || dbDirectory.isEmpty()) {
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
106
107 public void saveSettings() {
109
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
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
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
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 boolean executeValidationQuery(Connection conn, String validationQuery)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
static synchronized String getConfigSetting(String moduleName, String settingName)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.