Skip to content
Snippets Groups Projects
Unverified Commit d504cfb5 authored by Richard Cordovano's avatar Richard Cordovano Committed by GitHub
Browse files

Merge pull request #2133 from raman-bt/tsk_hosts

Added a tsk_hosts table and a HostManager to add/get hosts.
parents ef18ffee 577cf196
No related branches found
No related tags found
No related merge requests found
......@@ -150,6 +150,7 @@ private void addTables(Connection conn) throws TskCoreException {
createAnalysisResultsTables(stmt);
createTagTables(stmt);
createIngestTables(stmt);
createHostTables(stmt);
createAccountTables(stmt);
createEventTables(stmt);
createAttributeTables(stmt);
......@@ -390,6 +391,15 @@ private void createIngestTables(Statement stmt) throws SQLException {
+ "FOREIGN KEY(ingest_module_id) REFERENCES ingest_modules(ingest_module_id) ON DELETE CASCADE);");
}
private void createHostTables(Statement stmt) throws SQLException {
stmt.execute("CREATE TABLE tsk_hosts (id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
+ "name TEXT NOT NULL, " // host name
+ "status INTEGER DEFAULT 0, " // to indicate if the host was merged/deleted
+ "UNIQUE(name)) ");
}
private void createAccountTables(Statement stmt) throws SQLException {
stmt.execute("CREATE TABLE account_types (account_type_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
+ "type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
......
/*
* Sleuth Kit Data Model
*
* Copyright 2021-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.datamodel;
import java.util.Objects;
/**
*
* Encapsulates a host.
*/
public final class Host {
private final long id;
private final String name;
private HostStatus status;
Host(long id, String name) {
this(id, name, HostStatus.ACTIVE);
}
Host(long id, String name, HostStatus status) {
this.id = id;
this.name = name;
this.status = status;
}
/**
* Gets the row id for the host.
*
* @return Row id.
*/
public long getId() {
return id;
}
/**
* Gets the name for the host.
*
* @return Host name.
*/
public String getName() {
return name;
}
/**
* Gets the status for the host.
*
* @return Host status.
*/
public HostStatus getStatus() {
return status;
}
/**
* Sets the status for the host.
*
* @param status Host status.
*/
public void setStatus(HostStatus status) {
this.status = status;
}
@Override
public int hashCode() {
int hash = 5;
hash = 67 * hash + (int) (this.id ^ (this.id >>> 32));
hash = 67 * hash + Objects.hashCode(this.name);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Host other = (Host) obj;
if (this.id != other.id) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
/**
* Encapsulates status of host row.
*/
public enum HostStatus {
ACTIVE(0, "Active"),
MERGED(1, "Merged"),
DELETED(2, "Deleted");
private final int id;
private final String name;
HostStatus(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
String getName() {
return name;
}
public static HostStatus fromID(int typeId) {
for (HostStatus type : HostStatus.values()) {
if (type.ordinal() == typeId) {
return type;
}
}
return null;
}
}
}
/*
* Sleuth Kit Data Model
*
* Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.datamodel;
import com.google.common.base.Strings;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbConnection;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
/**
* Responsible for creating/updating/retrieving Hosts.
*
*/
public final class HostManager {
private static final Logger LOGGER = Logger.getLogger(HostManager.class.getName());
private final SleuthkitCase db;
/**
* Construct a HostManager for the given SleuthkitCase.
*
* @param skCase The SleuthkitCase
*
*/
HostManager(SleuthkitCase skCase) {
this.db = skCase;
}
/**
* Get or create host with specified name.
*
* @param name Host name.
* @param transaction Database transaction to use.
*
* @return Host with the specified name.
*
* @throws TskCoreException
*/
Host getOrCreateHost(String name, CaseDbTransaction transaction) throws TskCoreException {
// must have a name
if (Strings.isNullOrEmpty(name) ) {
throw new IllegalArgumentException("Host name is required.");
}
CaseDbConnection connection = transaction.getConnection();
// First search for host by name
Optional<Host> host = getHost(name, connection);
if (host.isPresent()) {
return host.get();
}
// couldn't find it, create a new host
return createHost(name, connection);
}
/**
* Get host with given name.
*
* @param name Host name to look for.
* @param connection Database connection to use.
*
* @return Optional with host. Optional.empty if no matching host is found.
*
* @throws TskCoreException
*/
Optional<Host> getHost(String name, CaseDbConnection connection ) throws TskCoreException {
String queryString = "SELECT * FROM tsk_hosts"
+ " WHERE LOWER(name) = LOWER('" + name + "')";
try (Statement s = connection.createStatement();
ResultSet rs = connection.executeQuery(s, queryString)) {
if (!rs.next()) {
return Optional.empty(); // no match found
} else {
return Optional.of(new Host(rs.getLong("id"), rs.getString("name"), Host.HostStatus.fromID(rs.getInt("status"))));
}
} catch (SQLException ex) {
throw new TskCoreException(String.format("Error getting host with name = %s", name), ex);
}
}
/**
* Create a host with given name.
*
* @param name Host name.
* @param connection Database connection to use.
* @return Newly created host.
* @throws TskCoreException
*/
private Host createHost(String name, CaseDbConnection connection) throws TskCoreException {
db.acquireSingleUserCaseWriteLock();
try {
String hostInsertSQL = "INSERT INTO tsk_hosts(name) VALUES (?)"; // NON-NLS
PreparedStatement preparedStatement = connection.getPreparedStatement(hostInsertSQL, Statement.RETURN_GENERATED_KEYS);
preparedStatement.clearParameters();
preparedStatement.setString(1, name);
connection.executeUpdate(preparedStatement);
// Read back the row id
try (ResultSet resultSet = preparedStatement.getGeneratedKeys();) {
if (resultSet.next()) {
return new Host(resultSet.getLong(1), name); //last_insert_rowid()
} else {
throw new SQLException("Error executing " + hostInsertSQL);
}
}
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, null, ex);
throw new TskCoreException(String.format("Error adding host with name = %s", name), ex);
} finally {
db.releaseSingleUserCaseWriteLock();
}
}
/**
* Get all hosts.
*
* @return Collection of hosts.
* @throws TskCoreException
*/
Set<Host> getHosts() throws TskCoreException {
String queryString = "SELECT * FROM tsk_hosts";
Set<Host> hosts = new HashSet<>();
try (CaseDbConnection connection = this.db.getConnection();
Statement s = connection.createStatement();
ResultSet rs = connection.executeQuery(s, queryString)) {
while (rs.next()) {
hosts.add(new Host(rs.getLong("id"), rs.getString("name"), Host.HostStatus.fromID(rs.getInt("status"))));
}
return hosts;
} catch (SQLException ex) {
throw new TskCoreException(String.format("Error getting hosts"), ex);
}
}
}
......@@ -212,6 +212,7 @@ public class SleuthkitCase {
private CaseDbAccessManager dbAccessManager;
private TaggingManager taggingMgr;
private ScoringManager scoringManager;
private HostManager hostManager;
 
private final Map<String, Set<Long>> deviceIdToDatasourceObjIdMap = new HashMap<>();
 
......@@ -391,6 +392,7 @@ private void init() throws Exception {
dbAccessManager = new CaseDbAccessManager(this);
taggingMgr = new TaggingManager(this);
scoringManager = new ScoringManager(this);
hostManager = new HostManager(this);
}
 
/**
......@@ -514,6 +516,17 @@ public ScoringManager getScoringManager() throws TskCoreException {
return scoringManager;
}
/**
* Gets the host manager for this case.
*
* @return The per case HostManager object.
*
* @throws org.sleuthkit.datamodel.TskCoreException
*/
public HostManager getHostManager() throws TskCoreException {
return hostManager;
}
/**
* Make sure the predefined artifact types are in the artifact types table.
*
......@@ -2242,14 +2255,22 @@ private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema8dot7(CaseDbSchem
acquireSingleUserCaseWriteLock();
try {
String dateDataType = "BIGINT";
String primaryKeyType = "BIGSERIAL";
if (this.dbType.equals(DbType.SQLITE)) {
dateDataType = "INTEGER";
primaryKeyType = "INTEGER";
}
statement.execute("ALTER TABLE data_source_info ADD COLUMN added_date_time "+ dateDataType);
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_settings TEXT");
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_name TEXT");
statement.execute("ALTER TABLE data_source_info ADD COLUMN acquisition_tool_version TEXT");
 
// create host table.
statement.execute("CREATE TABLE tsk_hosts (id " + primaryKeyType + " PRIMARY KEY, "
+ "name TEXT NOT NULL, " // host name
+ "status INTEGER DEFAULT 0, " // to indicate if the host was merged/deleted
+ "UNIQUE(name)) ");
return new CaseDbSchemaVersionNumber(8, 7);
 
} finally {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment