diff --git a/bindings/java/doxygen/artifact_catalog.dox b/bindings/java/doxygen/artifact_catalog.dox index 8bf2fcb6997187159772dbd7070012e7dc56784d..84acdf64bf24bec83289854736c004cfbceec998 100644 --- a/bindings/java/doxygen/artifact_catalog.dox +++ b/bindings/java/doxygen/artifact_catalog.dox @@ -98,6 +98,14 @@ Indication that the source artifact or file contains a keyword. Keywords are gro - TSK_KEYWORD_PREVIEW (Snippet of text around keyword) +--- +## TSK_MALWARE +Indicates the source file's malware status based on the score. A notable score means that the file has been detected to be malware. A score of none means that the file has been detected to not be malware. + +### REQUIRED ATTRIBUTES +None + + --- ## TSK_OBJECT_DETECTED Indicates that an object was detected in a media file. Typically used by computer vision software to classify images. diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties index c0791a15b0540b9b8dda248f5828a2a024c9815a..203f47fee0f51d32ac37ba0dff9809a455965aec 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties @@ -305,16 +305,15 @@ BlackboardAttribute.tskGeoLatitudeEnd.text=Ending Latitude BlackboardAttribute.tskGeoLongitudeStart.text=Starting Longitude BlackboardAttribute.tskGeoLongitudeEnd.text=Ending Longitude BlackboardAttribute.tskReadStatus.text=Read -DatabaseConnectionCheck.Everything=Invalid hostname, port number, username, and/or password. -DatabaseConnectionCheck.Hostname=Invalid hostname. -DatabaseConnectionCheck.Port=Invalid port number. +DatabaseConnectionCheck.Everything=Invalid hostname, port number, username, password, and firewall settings. +DatabaseConnectionCheck.Port=Verify that PostgreSQL server is running, it's port number, and firewall settings. DatabaseConnectionCheck.HostnameOrPort=Invalid hostname and/or port number. DatabaseConnectionCheck.Authentication=Invalid username and/or password. DatabaseConnectionCheck.Access=Invalid username and/or password. DatabaseConnectionCheck.ServerDiskSpace=PostgreSQL server issue. Check disk space and memory availabilty on the PostgreSQL server. DatabaseConnectionCheck.ServerRestart="PostgreSQL server issue. PostgreSQL server may need to be restarted. DatabaseConnectionCheck.InternalServerIssue=Internal PostgreSQL issue. Database may be corrupted. -DatabaseConnectionCheck.Connection=Invalid hostname, port, username, and/or password. +DatabaseConnectionCheck.Connection=Invalid hostname, port, username, and/or password. Check firewall settings. DatabaseConnectionCheck.Installation=Issue with installation. JDBC driver not found. DatabaseConnectionCheck.MissingHostname=Missing hostname. DatabaseConnectionCheck.MissingPort=Missing port number. diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED index c0791a15b0540b9b8dda248f5828a2a024c9815a..203f47fee0f51d32ac37ba0dff9809a455965aec 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED @@ -305,16 +305,15 @@ BlackboardAttribute.tskGeoLatitudeEnd.text=Ending Latitude BlackboardAttribute.tskGeoLongitudeStart.text=Starting Longitude BlackboardAttribute.tskGeoLongitudeEnd.text=Ending Longitude BlackboardAttribute.tskReadStatus.text=Read -DatabaseConnectionCheck.Everything=Invalid hostname, port number, username, and/or password. -DatabaseConnectionCheck.Hostname=Invalid hostname. -DatabaseConnectionCheck.Port=Invalid port number. +DatabaseConnectionCheck.Everything=Invalid hostname, port number, username, password, and firewall settings. +DatabaseConnectionCheck.Port=Verify that PostgreSQL server is running, it's port number, and firewall settings. DatabaseConnectionCheck.HostnameOrPort=Invalid hostname and/or port number. DatabaseConnectionCheck.Authentication=Invalid username and/or password. DatabaseConnectionCheck.Access=Invalid username and/or password. DatabaseConnectionCheck.ServerDiskSpace=PostgreSQL server issue. Check disk space and memory availabilty on the PostgreSQL server. DatabaseConnectionCheck.ServerRestart="PostgreSQL server issue. PostgreSQL server may need to be restarted. DatabaseConnectionCheck.InternalServerIssue=Internal PostgreSQL issue. Database may be corrupted. -DatabaseConnectionCheck.Connection=Invalid hostname, port, username, and/or password. +DatabaseConnectionCheck.Connection=Invalid hostname, port, username, and/or password. Check firewall settings. DatabaseConnectionCheck.Installation=Issue with installation. JDBC driver not found. DatabaseConnectionCheck.MissingHostname=Missing hostname. DatabaseConnectionCheck.MissingPort=Missing port number. diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle_ja.properties b/bindings/java/src/org/sleuthkit/datamodel/Bundle_ja.properties index 17e3b07892f5607730a5691418230d285af22a26..f8aeaf6b799884945e7d7055cb71b8e97d531dbd 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle_ja.properties +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle_ja.properties @@ -249,7 +249,6 @@ DatabaseConnectionCheck.Access=\u30e6\u30fc\u30b6\u30fc\u540d\u304b\u30d1\u30b9\ DatabaseConnectionCheck.Authentication=\u30e6\u30fc\u30b6\u30fc\u540d\u304b\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u7121\u52b9\u3067\u3059\u3002 DatabaseConnectionCheck.Connection=\u30db\u30b9\u30c8\u540d\u3001\u30dd\u30fc\u30c8\u3001\u30e6\u30fc\u30b6\u30fc\u540d\u3001\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u7121\u52b9\u3067\u3059\u3002 DatabaseConnectionCheck.Everything=\u30db\u30b9\u30c8\u540d\u3001\u30dd\u30fc\u30c8\u756a\u53f7\u3001\u30e6\u30fc\u30b6\u30fc\u540d\u3001\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u7121\u52b9\u3067\u3059\u3002 -DatabaseConnectionCheck.Hostname=\u7121\u52b9\u306a\u30db\u30b9\u30c8\u540d\u3002 DatabaseConnectionCheck.HostnameOrPort=\u30db\u30b9\u30c8\u540d\u3084\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059\u3002 DatabaseConnectionCheck.Installation=\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306b\u95a2\u3059\u308b\u554f\u984c\u3002 JDBC\u30c9\u30e9\u30a4\u30d0\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002 DatabaseConnectionCheck.InternalServerIssue=PostgreSQL\u306e\u5185\u90e8\u554f\u984c\u3002 \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u7834\u640d\u3057\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 diff --git a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java index f1dc2cfbec3ed560c54fc2e750e3b78f1de2b714..782c1ffe86ba0bf6fb00ebe5feb0c77eb3094259 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java +++ b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java @@ -40,6 +40,37 @@ class CaseDatabaseFactory { private final SQLHelper dbQueryHelper; private final DbCreationHelper dbCreationHelper; + // ssl=true: enables SSL encryption. + // NonValidatingFactory avoids hostname verification. + // sslmode=require: This mode makes the encryption mandatory and also requires the connection to fail if it can't be encrypted. + // In this mode, the JDBC driver accepts all server certificates, including self-signed ones. + final static String SSL_NONVERIFY_URL = "?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory&sslmode=require"; + + // ssl=true: enables SSL encryption. + // DefaultJavaSSLFactory: uses application's default JRE keystore to validate server certificate. + // sslmode=verify-ca: verifies that the server we are connecting to is trusted by CA. + final static String SSL_VERIFY_DEFAULT_URL = "?ssl=true&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory&sslmode=verify-ca"; + + /** + * Creates JDBC URL string for implementations that use custom keystore to + * validate PostgreSQL CA-signed SSL certificates. The class that performs + * SSL certificate validation must extend org.postgresql.ssl.WrappedFactory + * and generally must follow the same logic. + * + * ssl=true: enables SSL encryption. + * sslmode=verify-ca: verifies that the server we are connecting to is trusted by CA. + * + * @param customSslValidationClassName full canonical name of a Java class + * that performs custom SSL certificate + * validation. + * + * @return JDBS URL string used to connect to PosgreSQL server via CA-signed + * SSL certificate. + */ + static String getCustomPostrgesSslVerificationUrl(String customSslValidationClassName) { + return "?ssl=true&sslfactory=" + customSslValidationClassName + "&sslmode=verify-ca"; + } + /** * Create a new SQLite case * @@ -713,6 +744,19 @@ Connection getConnection(String databaseName) throws TskCoreException { .append('/') // NON-NLS .append(encodedDbName); + if (info.isSslEnabled()) { + if (info.isSslVerify()) { + if (info.getCustomSslValidationClassName().isBlank()) { + url.append(SSL_VERIFY_DEFAULT_URL); + } else { + // use custom SSL certificate validation class + url.append(getCustomPostrgesSslVerificationUrl(info.getCustomSslValidationClassName())); + } + } else { + url.append(SSL_NONVERIFY_URL); + } + } + Connection conn; try { Properties props = new Properties(); diff --git a/bindings/java/src/org/sleuthkit/datamodel/CaseDbConnectionInfo.java b/bindings/java/src/org/sleuthkit/datamodel/CaseDbConnectionInfo.java index fd4cb12c5f9e2c300cd8055edb257157931d5c8f..3fc1af058c216ac4179acd9ce2e8cb8b09527a17 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/CaseDbConnectionInfo.java +++ b/bindings/java/src/org/sleuthkit/datamodel/CaseDbConnectionInfo.java @@ -1,7 +1,7 @@ /* * Sleuth Kit Data Model * - * Copyright 2011-2015 Basis Technology Corp. + * Copyright 2011-2023 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,6 +34,9 @@ public class CaseDbConnectionInfo { private String userName; private String password; private DbType dbType; + private boolean sslEnabled = false; + private boolean sslVerify = false; + private String customSslValidationClassName; /** * The intent of this class is to hold any information needed to connect to @@ -54,12 +57,58 @@ public CaseDbConnectionInfo(String hostNameOrIP, String portNumber, String userN this.portNumber = portNumber; this.userName = userName; this.password = password; + this.sslEnabled = false; + this.sslVerify = false; if (dbType == DbType.SQLITE) { throw new IllegalArgumentException("SQLite database type invalid for CaseDbConnectionInfo. CaseDbConnectionInfo should be used only for remote database types."); } this.dbType = dbType; + this.customSslValidationClassName = ""; } - + + /** + * The intent of this class is to hold any information needed to connect to + * a remote database server, except for the actual database name. This + * constructor allows user to specify whether to use SSL to connect to + * database. This does not hold information to connect to a local database + * such as SQLite. + * + * This constructor allows to specify a Java class that performs custom + * PostgreQSL server SSL certificate validation (if 'sslVerify' is set to + * 'true'). If not specified, the application's default JRE keystore will be + * used. + * + * It can be used generically to hold remote database connection + * information. + * + * @param hostNameOrIP the host name + * @param portNumber the port number + * @param userName the user name + * @param password the password + * @param dbType the database type + * @param sslEnabled a flag whether SSL is enabled + * @param sslVerify 'true' if SSL certificate needs to be CA verified. 'false' if self-signed certificates should be accepted. + * @param customSslValidationClassName full canonical name of a Java class + * that performs custom SSL certificate + * validation. If blank, the + * application's default JRE keystore + * will be used. + */ + public CaseDbConnectionInfo(String hostNameOrIP, String portNumber, String userName, String password, DbType dbType, + boolean sslEnabled, boolean sslVerify, String customSslValidationClassName) { + this.hostNameOrIP = hostNameOrIP; + this.portNumber = portNumber; + this.userName = userName; + this.password = password; + this.sslEnabled = sslEnabled; + this.sslVerify = sslVerify; + if (dbType == DbType.SQLITE) { + throw new IllegalArgumentException("SQLite database type invalid for CaseDbConnectionInfo. CaseDbConnectionInfo should be used only for remote database types."); + } + this.dbType = dbType; + this.customSslValidationClassName = customSslValidationClassName; + } + public DbType getDbType() { return this.dbType; } @@ -99,4 +148,28 @@ public void setUserName(String user) { public void setPassword(String pass) { this.password = pass; } + + public boolean isSslEnabled() { + return sslEnabled; + } + + public void setSslEnabled(boolean sslEnabled) { + this.sslEnabled = sslEnabled; + } + + public boolean isSslVerify() { + return sslVerify; + } + + public void setSslVerify(boolean sslVerify) { + this.sslVerify = sslVerify; + } + + public String getCustomSslValidationClassName() { + return customSslValidationClassName; + } + + public void setCustomSslValidationClassName(String customSslValidationClassName) { + this.customSslValidationClassName = customSslValidationClassName; + } } diff --git a/bindings/java/src/org/sleuthkit/datamodel/HostAddressManager.java b/bindings/java/src/org/sleuthkit/datamodel/HostAddressManager.java index da259858280e0fd8b3285d88673e2ba60bcf8af7..99ac9843d3528a7fcdf6cfc287bb5bde74f7147c 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/HostAddressManager.java +++ b/bindings/java/src/org/sleuthkit/datamodel/HostAddressManager.java @@ -283,7 +283,7 @@ public void assignHostToAddress(Host host, HostAddress hostAddress, Long time, C * * @return List of addresses, may be empty. */ - List<HostAddress> getHostAddressesAssignedTo(Host host) throws TskCoreException { + public List<HostAddress> getHostAddressesAssignedTo(Host host) throws TskCoreException { String queryString = "SELECT addr_obj_id FROM tsk_host_address_map " + " WHERE host_id = " + host.getHostId(); diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java index ceee46a7218d39cecb3768191db27992e2dfa86a..9186a4aa797586277fd2663805d57f32108c94a3 100755 --- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java +++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java @@ -505,14 +505,14 @@ private Optional<OsAccount> getOsAccountByAddr(String uniqueId, Host host, CaseD String queryString = "SELECT accounts.os_account_obj_id as os_account_obj_id, accounts.login_name, accounts.full_name, " + " accounts.realm_id, accounts.addr, accounts.signature, " - + " accounts.type, accounts.status, accounts.created_date, accounts.db_status, " + + " accounts.type, accounts.status, accounts.created_date, accounts.db_status, " + " realms.realm_name as realm_name, realms.realm_addr as realm_addr, realms.realm_signature, realms.scope_host_id, realms.scope_confidence, realms.db_status as realm_db_status " + " FROM tsk_os_accounts as accounts" - + " LEFT JOIN tsk_os_account_realms as realms" + + " LEFT JOIN tsk_os_account_realms as realms" + " ON accounts.realm_id = realms.id" + " WHERE " + whereHostClause + " AND accounts.db_status = " + OsAccount.OsAccountDbStatus.ACTIVE.getId() - + " AND LOWER(accounts.addr) = LOWER('" + uniqueId + "')"; + + " AND LOWER(accounts.addr) = LOWER('" + uniqueId + "')"; db.acquireSingleUserCaseReadLock(); try (Statement s = connection.createStatement(); diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index aec77700f9293b1ef043304cc6d9bcf80bfe1df8..0ecdf3e75db59a6a10644b4b3a97229f62a6c91e 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -1,7 +1,7 @@ /* * Sleuth Kit Data Model * - * Copyright 2011-2021 Basis Technology Corp. + * Copyright 2011-2023 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -112,6 +112,10 @@ public class SleuthkitCase { private static final ResourceBundle bundle = ResourceBundle.getBundle("org.sleuthkit.datamodel.Bundle"); private static final int IS_REACHABLE_TIMEOUT_MS = 1000; private static final String SQL_ERROR_CONNECTION_GROUP = "08"; + // either one of these mean connection was rejected by Postgres server + private static final String SQL_CONNECTION_REJECTED = "08004"; + private static final String UNABLE_TO_VERIFY_SSL = "08006"; + private static final String SQL_ERROR_AUTHENTICATION_GROUP = "28"; private static final String SQL_ERROR_PRIVILEGE_GROUP = "42"; private static final String SQL_ERROR_RESOURCE_GROUP = "53"; @@ -289,24 +293,47 @@ public static void tryConnect(CaseDbConnectionInfo info) throws TskCoreException try { Class.forName("org.postgresql.Driver"); //NON-NLS - Connection conn = DriverManager.getConnection("jdbc:postgresql://" + info.getHost() + ":" + info.getPort() + "/postgres", info.getUserName(), info.getPassword()); //NON-NLS + String connectionURL = "jdbc:postgresql://" + info.getHost() + ":" + info.getPort() + "/postgres"; + if (info.isSslEnabled()) { + if (info.isSslVerify()) { + if (info.getCustomSslValidationClassName().isBlank()) { + connectionURL += CaseDatabaseFactory.SSL_VERIFY_DEFAULT_URL; + } else { + // use custom SSL certificate validation class + connectionURL += CaseDatabaseFactory.getCustomPostrgesSslVerificationUrl(info.getCustomSslValidationClassName()); + } + } else { + connectionURL += CaseDatabaseFactory.SSL_NONVERIFY_URL; + } + } + Connection conn = DriverManager.getConnection(connectionURL, info.getUserName(), info.getPassword()); //NON-NLS if (conn != null) { conn.close(); } } catch (SQLException ex) { String result; String sqlState = ex.getSQLState().toLowerCase(); - if (sqlState.startsWith(SQL_ERROR_CONNECTION_GROUP)) { - try { - if (InetAddress.getByName(info.getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) { - // if we can reach the host, then it's probably port problem - result = bundle.getString("DatabaseConnectionCheck.Port"); //NON-NLS + if (sqlState.startsWith(SQL_ERROR_CONNECTION_GROUP)) { + if (SQL_CONNECTION_REJECTED.equals(ex.getSQLState())) { + if (info.isSslEnabled()) { + result = "Server rejected the SSL connection attempt. Check SSL configuration."; } else { - result = bundle.getString("DatabaseConnectionCheck.HostnameOrPort"); //NON-NLS + result = "Server rejected the connection attempt. Check server configuration."; + } + } else if (UNABLE_TO_VERIFY_SSL.equals(ex.getSQLState())) { + result = "Unable to verify SSL certificates. Check SSL configuration."; + } else { + try { + if (InetAddress.getByName(info.getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) { + // if we can reach the host, then it's probably port problem + result = bundle.getString("DatabaseConnectionCheck.Port"); //NON-NLS + } else { + result = bundle.getString("DatabaseConnectionCheck.HostnameOrPort"); //NON-NLS + } + } catch (IOException | MissingResourceException any) { + // it may be anything + result = bundle.getString("DatabaseConnectionCheck.Everything"); //NON-NLS } - } catch (IOException | MissingResourceException any) { - // it may be anything - result = bundle.getString("DatabaseConnectionCheck.Everything"); //NON-NLS } } else if (sqlState.startsWith(SQL_ERROR_AUTHENTICATION_GROUP)) { result = bundle.getString("DatabaseConnectionCheck.Authentication"); //NON-NLS @@ -357,27 +384,20 @@ private SleuthkitCase(String dbPath, SleuthkitJNI.CaseDbHandle caseHandle, DbTyp /** * Private constructor, clients must use newCase() or openCase() method to * create an instance of this class. - * - * @param host The PostgreSQL database server. - * @param port The port to use connect to the PostgreSQL database - * server. + * + * @param info CaseDbConnectionInfo object with database connection info * @param dbName The name of the case database. - * @param userName The user name to use to connect to the case database. - * @param password The password to use to connect to the case database. * @param caseHandle A handle to a case database object in the native code - * @param dbType The type of database we're dealing with SleuthKit - * layer. * @param caseDirPath The path to the root case directory. * @param contentProvider Custom provider for file content (can be null). - * - * @throws Exception + * @throws Exception */ - private SleuthkitCase(String host, int port, String dbName, String userName, String password, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, DbType dbType, ContentStreamProvider contentProvider) throws Exception { + private SleuthkitCase(CaseDbConnectionInfo info, String dbName, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, ContentStreamProvider contentProvider) throws Exception { this.dbPath = ""; this.databaseName = dbName; - this.dbType = dbType; + this.dbType = info.getDbType(); this.caseDirPath = caseDirPath; - this.connections = new PostgreSQLConnections(host, port, dbName, userName, password); + this.connections = new PostgreSQLConnections(info, dbName); this.caseHandle = caseHandle; this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier(); this.contentProvider = contentProvider; @@ -3057,7 +3077,7 @@ public static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo i * are able, but do not lose any information if unable. */ final SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.openCaseDb(databaseName, info); - return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()), databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDir, info.getDbType(), contentProvider); + return new SleuthkitCase(info, databaseName, caseHandle, caseDir, contentProvider); } catch (PropertyVetoException exp) { // In this case, the JDBC driver doesn't support PostgreSQL. Use the generic message here. throw new TskCoreException(exp.getMessage(), exp); @@ -3162,8 +3182,7 @@ public static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info, factory.createCaseDatabase(); final SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.openCaseDb(databaseName, info); - return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()), - databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDirPath, info.getDbType(), contentProvider); + return new SleuthkitCase(info, databaseName, caseHandle, caseDirPath, contentProvider); } catch (PropertyVetoException exp) { // In this case, the JDBC driver doesn't support PostgreSQL. Use the generic message here. throw new TskCoreException(exp.getMessage(), exp); @@ -13384,13 +13403,28 @@ public CaseDbConnection getPooledConnection() throws SQLException { */ private final class PostgreSQLConnections extends ConnectionPool { - PostgreSQLConnections(String host, int port, String dbName, String userName, String password) throws PropertyVetoException, UnsupportedEncodingException { + PostgreSQLConnections(CaseDbConnectionInfo info, String dbName) throws PropertyVetoException, UnsupportedEncodingException { + ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setDriverClass("org.postgresql.Driver"); //loads the jdbc driver - comboPooledDataSource.setJdbcUrl("jdbc:postgresql://" + host + ":" + port + "/" - + URLEncoder.encode(dbName, StandardCharsets.UTF_8.toString())); - comboPooledDataSource.setUser(userName); - comboPooledDataSource.setPassword(password); + + String connectionURL = "jdbc:postgresql://" + info.getHost() + ":" + Integer.valueOf(info.getPort()) + "/" + + URLEncoder.encode(dbName, StandardCharsets.UTF_8.toString()); + if (info.isSslEnabled()) { + if (info.isSslVerify()) { + if (info.getCustomSslValidationClassName().isBlank()) { + connectionURL += CaseDatabaseFactory.SSL_VERIFY_DEFAULT_URL; + } else { + // use custom SSL certificate validation class + connectionURL += CaseDatabaseFactory.getCustomPostrgesSslVerificationUrl(info.getCustomSslValidationClassName()); + } + } else { + connectionURL += CaseDatabaseFactory.SSL_NONVERIFY_URL; + } + } + comboPooledDataSource.setJdbcUrl(connectionURL); + comboPooledDataSource.setUser(info.getUserName()); + comboPooledDataSource.setPassword(info.getPassword()); comboPooledDataSource.setAcquireIncrement(2); comboPooledDataSource.setInitialPoolSize(5); comboPooledDataSource.setMinPoolSize(5); diff --git a/tsk/fs/fs_attrlist.c b/tsk/fs/fs_attrlist.c index ede0a7c0ac3358147079639c7fec15ebd1233ad1..40a262a3c65e4dfb77e58d48f5e25a33e1a7eaed 100644 --- a/tsk/fs/fs_attrlist.c +++ b/tsk/fs/fs_attrlist.c @@ -341,6 +341,13 @@ tsk_fs_attrlist_get_name_type(const TSK_FS_ATTRLIST * a_fs_attrlist, || (fs_attr_ok->id > fs_attr_cur->id)) fs_attr_ok = fs_attr_cur; } + + else if ((name) && (fs_attr_cur->name) && fs_attr_cur->type == TSK_FS_ATTR_TYPE_NTFS_DATA && !stricmp(fs_attr_cur->name, name)) { + // NTFS data streams should do case insensitive compare + // make sure we return the lowest if multiple exist + if ((fs_attr_ok == NULL) || (fs_attr_ok->id > fs_attr_cur->id)) + fs_attr_ok = fs_attr_cur; + } } }