mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 6065-contactbook-personas
This commit is contained in:
commit
a1fc560666
@ -98,6 +98,8 @@
|
||||
tofile="${ext.dir}/sleuthkit-${TSK_VERSION}.jar"/>
|
||||
<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.25.2.jar"
|
||||
tofile="${ext.dir}/sqlite-jdbc-3.25.2.jar"/>
|
||||
<copy file="${env.TSK_HOME}/bindings/java/lib/postgresql-9.4.1211.jre7.jar"
|
||||
tofile="${ext.dir}/postgresql-9.4.1211.jre7.jar"/>
|
||||
<copy file="${env.TSK_HOME}/bindings/java/lib/mchange-commons-java-0.2.9.jar"
|
||||
tofile="${ext.dir}/mchange-commons-java-0.2.9.jar"/>
|
||||
<copy file="${env.TSK_HOME}/bindings/java/lib/c3p0-0.9.5.jar"
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* 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.autopsy.centralrepository.datamodel;
|
||||
|
||||
/**
|
||||
* Encapsulates the concept of an examiner.
|
||||
*/
|
||||
final public class CentralRepoExaminer {
|
||||
|
||||
private final long id; // Row id in the examiners table in central repo database.
|
||||
private final String loginName;
|
||||
|
||||
public CentralRepoExaminer(long id, String loginName) {
|
||||
this.id = id;
|
||||
this.loginName = loginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the login name of examiner.
|
||||
*
|
||||
* @return login name
|
||||
*/
|
||||
public String getLoginName() {
|
||||
return this.loginName;
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,6 @@ import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
|
||||
/**
|
||||
* Main interface for interacting with the database
|
||||
@ -163,21 +162,15 @@ public interface CentralRepository {
|
||||
void updateCase(CorrelationCase eamCase) throws CentralRepoException;
|
||||
|
||||
/**
|
||||
* Updates the examiners table, by adding current logged in user to
|
||||
* examiners table, if not already in there.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error.
|
||||
* Queries the examiner table for the given user name.
|
||||
* Adds a row if the user is not found in the examiner table.
|
||||
*
|
||||
* @param examinerLoginName user name to look for.
|
||||
* @return CentralRepoExaminer for the given user name.
|
||||
* @throws CentralRepoException If there is an error in looking up or
|
||||
* inserting the user in the examiners table.
|
||||
*/
|
||||
void updateExaminers() throws CentralRepoException;
|
||||
|
||||
/**
|
||||
* Get the Examiner object for the current logged in user.
|
||||
*
|
||||
* @return Examiner Current examiner.
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
Examiner getCurrentCentralRepoExaminer() throws CentralRepoException;
|
||||
CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException;
|
||||
|
||||
/**
|
||||
* Retrieves Central Repo case based on an Autopsy Case
|
||||
@ -872,10 +865,5 @@ public interface CentralRepository {
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException;
|
||||
|
||||
|
||||
/**
|
||||
* Clears all caches.
|
||||
*/
|
||||
void clearCaches();
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-2020 Basis Technology Corp.
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -27,7 +27,7 @@ import java.sql.SQLException;
|
||||
* the results themselves.
|
||||
*
|
||||
*/
|
||||
public interface CentralRepositoryDbQueryCallback {
|
||||
interface CentralRepositoryDbQueryCallback {
|
||||
|
||||
/**
|
||||
* Process the resultset from a query.
|
||||
|
@ -27,7 +27,6 @@ import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
@ -116,7 +115,7 @@ public class Persona {
|
||||
}
|
||||
|
||||
// Persona name to use if no name is specified.
|
||||
private static final String DEFAULT_PERSONA_NAME = "NoName";
|
||||
private static final String DEFAULT_PERSONA_NAME = "Unknown";
|
||||
|
||||
// primary key in the Personas table in CR database
|
||||
private final long id;
|
||||
@ -126,7 +125,7 @@ public class Persona {
|
||||
private final long createdDate;
|
||||
private final long modifiedDate;
|
||||
private final PersonaStatus status;
|
||||
private final Examiner examiner;
|
||||
private final CentralRepoExaminer examiner;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
@ -156,11 +155,11 @@ public class Persona {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Examiner getExaminer() {
|
||||
public CentralRepoExaminer getExaminer() {
|
||||
return examiner;
|
||||
}
|
||||
|
||||
Persona(long id, String uuidStr, String name, String comment, long created_date, long modified_date, PersonaStatus status, Examiner examiner) {
|
||||
Persona(long id, String uuidStr, String name, String comment, long created_date, long modified_date, PersonaStatus status, CentralRepoExaminer examiner) {
|
||||
this.id = id;
|
||||
this.uuidStr = uuidStr;
|
||||
this.name = name;
|
||||
@ -207,7 +206,7 @@ public class Persona {
|
||||
private static Persona createPersona(String name, String comment, PersonaStatus status) throws CentralRepoException {
|
||||
// generate a UUID for the persona
|
||||
String uuidStr = UUID.randomUUID().toString();
|
||||
Examiner examiner = CentralRepository.getInstance().getCurrentCentralRepoExaminer();
|
||||
CentralRepoExaminer examiner = CentralRepository.getInstance().getOrInsertExaminer(System.getProperty("user.name"));
|
||||
|
||||
Instant instant = Instant.now();
|
||||
Long timeStampMillis = instant.toEpochMilli();
|
||||
@ -240,7 +239,7 @@ public class Persona {
|
||||
*/
|
||||
public PersonaAccount addAccountToPersona(CentralRepoAccount account, String justification, Persona.Confidence confidence) throws CentralRepoException {
|
||||
|
||||
Examiner currentExaminer = CentralRepository.getInstance().getCurrentCentralRepoExaminer();
|
||||
CentralRepoExaminer currentExaminer = CentralRepository.getInstance().getOrInsertExaminer(System.getProperty("user.name"));
|
||||
|
||||
Instant instant = Instant.now();
|
||||
Long timeStampMillis = instant.toEpochMilli();
|
||||
@ -263,19 +262,18 @@ public class Persona {
|
||||
*/
|
||||
private static class PersonaQueryCallback implements CentralRepositoryDbQueryCallback {
|
||||
|
||||
private Persona persona = null;
|
||||
private final Collection<Persona> personaList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void process(ResultSet rs) throws SQLException {
|
||||
|
||||
while (rs.next()) {
|
||||
Examiner examiner = new Examiner(
|
||||
CentralRepoExaminer examiner = new CentralRepoExaminer(
|
||||
rs.getInt("examiner_id"),
|
||||
rs.getString("login_name"),
|
||||
rs.getString("display_name"));
|
||||
rs.getString("login_name"));
|
||||
|
||||
PersonaStatus status = PersonaStatus.fromId(rs.getInt("status_id"));
|
||||
persona = new Persona(
|
||||
Persona persona = new Persona(
|
||||
rs.getInt("id"),
|
||||
rs.getString("uuid"),
|
||||
rs.getString("name"),
|
||||
@ -285,14 +283,24 @@ public class Persona {
|
||||
status,
|
||||
examiner
|
||||
);
|
||||
|
||||
personaList.add(persona);
|
||||
}
|
||||
}
|
||||
|
||||
Persona getPersona() {
|
||||
return persona;
|
||||
Collection<Persona> getPersonas() {
|
||||
return Collections.unmodifiableCollection(personaList);
|
||||
}
|
||||
};
|
||||
|
||||
// Partial query string to select from personas table,
|
||||
// just supply the where clause.
|
||||
private static final String PERSONA_QUERY =
|
||||
"SELECT p.id, p.uuid, p.name, p.comment, p.created_date, p.modified_date, p.status_id, p.examiner_id, e.login_name, e.display_name "
|
||||
+ "FROM personas as p "
|
||||
+ "INNER JOIN examiners as e ON e.id = p.examiner_id ";
|
||||
|
||||
|
||||
/**
|
||||
* Gets the row from the Personas table with the given UUID, creates and
|
||||
* returns the Persona from that data.
|
||||
@ -306,41 +314,39 @@ public class Persona {
|
||||
*/
|
||||
private static Persona getPersonaByUUID(String uuid) throws CentralRepoException {
|
||||
|
||||
String queryClause = "SELECT p.id, p.uuid, p.name, p.comment, p.created_date, p.modified_date, p.status_id, p.examiner_id, e.login_name, e.display_name "
|
||||
+ "FROM personas as p "
|
||||
+ "INNER JOIN examiners as e ON e.id = p.examiner_id "
|
||||
String queryClause =
|
||||
PERSONA_QUERY
|
||||
+ "WHERE p.uuid = '" + uuid + "'";
|
||||
|
||||
PersonaQueryCallback queryCallback = new PersonaQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersona();
|
||||
Collection<Persona> personas = queryCallback.getPersonas();
|
||||
|
||||
return personas.isEmpty() ? null : personas.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the row from the Personas table with the given id, creates and
|
||||
* returns the Persona from that data.
|
||||
* Gets the rows from the Personas table with matching name.
|
||||
*
|
||||
* @param id Persona id to match.
|
||||
* @return Persona matching the given UUID, may be null if no match is
|
||||
* found.
|
||||
* @param partialName Name substring to match.
|
||||
* @return Collection of personas matching the given name substring, may be
|
||||
* empty if no match is found.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in querying the
|
||||
* Personas table.
|
||||
*/
|
||||
public static Persona getPersonaById(long id) throws CentralRepoException {
|
||||
public static Collection<Persona> getPersonaByName(String partialName) throws CentralRepoException {
|
||||
|
||||
String queryClause = "SELECT p.id, p.uuid, p.name, p.comment, p.created_date, p.modified_date, p.status_id, p.examiner_id, e.login_name, e.display_name "
|
||||
+ "FROM personas as p "
|
||||
+ "INNER JOIN examiners as e ON e.id = p.examiner_id "
|
||||
+ "WHERE p.id = " + id;
|
||||
String queryClause = PERSONA_QUERY
|
||||
+ "WHERE LOWER(p.name) LIKE " + "LOWER('%" + partialName + "%')" ;
|
||||
|
||||
PersonaQueryCallback queryCallback = new PersonaQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersona();
|
||||
return queryCallback.getPersonas();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an alias for the Persona.
|
||||
*
|
||||
@ -403,32 +409,7 @@ public class Persona {
|
||||
public Collection<PersonaAccount> getPersonaAccounts() throws CentralRepoException {
|
||||
return PersonaAccount.getPersonaAccountsForPersona(this.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the Persona for the specified Account.
|
||||
*
|
||||
* @param accountId Id of account for which to get the Personas for.
|
||||
* @return Collection of PersonaAccounts. may be empty.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in getting the
|
||||
* persona_account.
|
||||
*/
|
||||
public static Collection<PersonaAccount> getPersonaAccountsForAccount(long accountId) throws CentralRepoException {
|
||||
return PersonaAccount.getPersonaAccountsForAccount(accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all accounts associated with the persona.
|
||||
*
|
||||
* @return Collection of all accounts associated with the given persona, may
|
||||
* be empty.
|
||||
* @throws CentralRepoException If there is an error in getting the
|
||||
* accounts.
|
||||
*/
|
||||
public Collection<CentralRepoAccount> getAccounts() throws CentralRepoException {
|
||||
return PersonaAccount.getAccountsForPersona(this.getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback to process a query that gets cases for account instances of an
|
||||
* account
|
||||
@ -464,7 +445,7 @@ public class Persona {
|
||||
Collection<CorrelationCase> casesForPersona = new ArrayList<>();
|
||||
|
||||
// get all accounts for this persona
|
||||
Collection<CentralRepoAccount> accounts = this.getAccounts();
|
||||
Collection<CentralRepoAccount> accounts = PersonaAccount.getAccountsForPersona(this.getId());
|
||||
for (CentralRepoAccount account : accounts) {
|
||||
int corrTypeId = account.getAccountType().getCorrelationTypeId();
|
||||
CorrelationAttributeInstance.Type correlationType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId);
|
||||
@ -527,7 +508,7 @@ public class Persona {
|
||||
public Collection<CorrelationDataSource> getDataSources() throws CentralRepoException {
|
||||
Collection<CorrelationDataSource> correlationDataSources = new ArrayList<>();
|
||||
|
||||
Collection<CentralRepoAccount> accounts = this.getAccounts();
|
||||
Collection<CentralRepoAccount> accounts = PersonaAccount.getAccountsForPersona(this.getId());
|
||||
for (CentralRepoAccount account : accounts) {
|
||||
int corrTypeId = account.getAccountType().getCorrelationTypeId();
|
||||
CorrelationAttributeInstance.Type correlationType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId);
|
||||
@ -563,10 +544,9 @@ public class Persona {
|
||||
while (resultSet.next()) {
|
||||
|
||||
// examiner that created the persona
|
||||
Examiner personaExaminer = new Examiner(
|
||||
CentralRepoExaminer personaExaminer = new CentralRepoExaminer(
|
||||
resultSet.getInt("persona_examiner_id"),
|
||||
resultSet.getString("persona_examiner_login_name"),
|
||||
resultSet.getString("persona_examiner_display_name"));
|
||||
resultSet.getString("persona_examiner_login_name"));
|
||||
|
||||
// create persona
|
||||
PersonaStatus status = PersonaStatus.fromId(resultSet.getInt("status_id"));
|
||||
@ -653,7 +633,7 @@ public class Persona {
|
||||
* @return Collection of personas, may be empty.
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
public static Collection<Persona> getPersonaForDataSource(CorrelationDataSource dataSource) throws CentralRepoException {
|
||||
public static Collection<Persona> getPersonasForDataSource(CorrelationDataSource dataSource) throws CentralRepoException {
|
||||
Collection<Persona> personaList = new ArrayList<>();
|
||||
|
||||
Collection<CentralRepoAccount.CentralRepoAccountType> accountTypes = CentralRepository.getInstance().getAllAccountTypes();
|
||||
|
@ -23,7 +23,6 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
|
||||
/**
|
||||
* This class represents an association between a Persona and an Account.
|
||||
@ -39,9 +38,9 @@ public class PersonaAccount {
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
private final long dateAdded;
|
||||
private final Examiner examiner;
|
||||
private final CentralRepoExaminer examiner;
|
||||
|
||||
public PersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence, long dateAdded, Examiner examiner) {
|
||||
public PersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence, long dateAdded, CentralRepoExaminer examiner) {
|
||||
this.persona = persona;
|
||||
this.account = account;
|
||||
this.justification = justification;
|
||||
@ -70,7 +69,7 @@ public class PersonaAccount {
|
||||
return dateAdded;
|
||||
}
|
||||
|
||||
public Examiner getExaminer() {
|
||||
public CentralRepoExaminer getExaminer() {
|
||||
return examiner;
|
||||
}
|
||||
|
||||
@ -86,16 +85,14 @@ public class PersonaAccount {
|
||||
|
||||
while (rs.next()) {
|
||||
// examiner that created the persona/account association
|
||||
Examiner paExaminer = new Examiner(
|
||||
CentralRepoExaminer paExaminer = new CentralRepoExaminer(
|
||||
rs.getInt("pa_examiner_id"),
|
||||
rs.getString("pa_examiner_login_name"),
|
||||
rs.getString("pa_examiner_display_name"));
|
||||
rs.getString("pa_examiner_login_name"));
|
||||
|
||||
// examiner that created the persona
|
||||
Examiner personaExaminer = new Examiner(
|
||||
CentralRepoExaminer personaExaminer = new CentralRepoExaminer(
|
||||
rs.getInt("persona_examiner_id"),
|
||||
rs.getString("persona_examiner_login_name"),
|
||||
rs.getString("persona_examiner_display_name"));
|
||||
rs.getString("persona_examiner_login_name"));
|
||||
|
||||
// create persona
|
||||
Persona.PersonaStatus status = Persona.PersonaStatus.fromId(rs.getInt("status_id"));
|
||||
@ -175,7 +172,7 @@ public class PersonaAccount {
|
||||
* @throws CentralRepoException If there is an error in getting the
|
||||
* persona_account.
|
||||
*/
|
||||
static Collection<PersonaAccount> getPersonaAccountsForAccount(long accountId) throws CentralRepoException {
|
||||
public static Collection<PersonaAccount> getPersonaAccountsForAccount(long accountId) throws CentralRepoException {
|
||||
String queryClause = PERSONA_ACCOUNTS_QUERY_CALUSE
|
||||
+ " WHERE persona_accounts.account_id = " + accountId;
|
||||
|
||||
@ -184,6 +181,27 @@ public class PersonaAccount {
|
||||
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the Persona associated with all the accounts matching the given
|
||||
* account identifier substring.
|
||||
*
|
||||
* @param accountIdentifierSubstring Account identifier substring to search
|
||||
* for.
|
||||
* @return Collection of PersonaAccounts. may be empty.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in getting the
|
||||
* persona_account.
|
||||
*/
|
||||
public static Collection<PersonaAccount> getPersonaAccountsForAccountIdentifier(String accountIdentifierSubstring) throws CentralRepoException {
|
||||
String queryClause = PERSONA_ACCOUNTS_QUERY_CALUSE
|
||||
+ " WHERE LOWER(accounts.account_unique_identifier) LIKE LOWER('%" + accountIdentifierSubstring + "%')";
|
||||
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to process a query that gets all accounts belonging to a
|
||||
|
@ -25,7 +25,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
@ -40,7 +39,7 @@ public class PersonaAlias {
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
private final long dateAdded;
|
||||
private final Examiner examiner;
|
||||
private final CentralRepoExaminer examiner;
|
||||
|
||||
public long getPersonaId() {
|
||||
return personaId;
|
||||
@ -62,11 +61,11 @@ public class PersonaAlias {
|
||||
return dateAdded;
|
||||
}
|
||||
|
||||
public Examiner getExaminer() {
|
||||
public CentralRepoExaminer getExaminer() {
|
||||
return examiner;
|
||||
}
|
||||
|
||||
public PersonaAlias(long personaId, String alias, String justification, Persona.Confidence confidence, long dateAdded, Examiner examiner) {
|
||||
public PersonaAlias(long personaId, String alias, String justification, Persona.Confidence confidence, long dateAdded, CentralRepoExaminer examiner) {
|
||||
this.personaId = personaId;
|
||||
this.alias = alias;
|
||||
this.justification = justification;
|
||||
@ -88,7 +87,7 @@ public class PersonaAlias {
|
||||
*/
|
||||
static PersonaAlias addPersonaAlias(Persona persona, String alias, String justification, Persona.Confidence confidence) throws CentralRepoException {
|
||||
|
||||
Examiner examiner = CentralRepository.getInstance().getCurrentCentralRepoExaminer();
|
||||
CentralRepoExaminer examiner = CentralRepository.getInstance().getOrInsertExaminer(System.getProperty("user.name"));
|
||||
|
||||
Instant instant = Instant.now();
|
||||
Long timeStampMillis = instant.toEpochMilli();
|
||||
@ -118,10 +117,9 @@ public class PersonaAlias {
|
||||
public void process(ResultSet rs) throws SQLException {
|
||||
|
||||
while (rs.next()) {
|
||||
Examiner examiner = new Examiner(
|
||||
CentralRepoExaminer examiner = new CentralRepoExaminer(
|
||||
rs.getInt("examiner_id"),
|
||||
rs.getString("login_name"),
|
||||
rs.getString("display_name"));
|
||||
rs.getString("login_name"));
|
||||
|
||||
PersonaAlias alias = new PersonaAlias(
|
||||
rs.getLong("persona_id"),
|
||||
|
@ -25,7 +25,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
@ -43,7 +42,7 @@ public class PersonaMetadata {
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
private final long dateAdded;
|
||||
private final Examiner examiner;
|
||||
private final CentralRepoExaminer examiner;
|
||||
|
||||
public long getPersonaId() {
|
||||
return personaId;
|
||||
@ -69,11 +68,11 @@ public class PersonaMetadata {
|
||||
return dateAdded;
|
||||
}
|
||||
|
||||
public Examiner getExaminer() {
|
||||
public CentralRepoExaminer getExaminer() {
|
||||
return examiner;
|
||||
}
|
||||
|
||||
public PersonaMetadata(long personaId, String name, String value, String justification, Persona.Confidence confidence, long dateAdded, Examiner examiner) {
|
||||
public PersonaMetadata(long personaId, String name, String value, String justification, Persona.Confidence confidence, long dateAdded, CentralRepoExaminer examiner) {
|
||||
this.personaId = personaId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
@ -97,7 +96,7 @@ public class PersonaMetadata {
|
||||
*/
|
||||
static PersonaMetadata addPersonaMetadata(long personaId, String name, String value, String justification, Persona.Confidence confidence) throws CentralRepoException {
|
||||
|
||||
Examiner examiner = CentralRepository.getInstance().getCurrentCentralRepoExaminer();
|
||||
CentralRepoExaminer examiner = CentralRepository.getInstance().getOrInsertExaminer(System.getProperty("user.name"));
|
||||
|
||||
Instant instant = Instant.now();
|
||||
Long timeStampMillis = instant.toEpochMilli();
|
||||
@ -128,10 +127,9 @@ public class PersonaMetadata {
|
||||
public void process(ResultSet rs) throws SQLException {
|
||||
|
||||
while (rs.next()) {
|
||||
Examiner examiner = new Examiner(
|
||||
CentralRepoExaminer examiner = new CentralRepoExaminer(
|
||||
rs.getInt("examiner_id"),
|
||||
rs.getString("login_name"),
|
||||
rs.getString("display_name"));
|
||||
rs.getString("login_name"));
|
||||
|
||||
PersonaMetadata metaData = new PersonaMetadata(
|
||||
rs.getLong("persona_id"),
|
||||
|
@ -71,8 +71,6 @@ final class PostgresCentralRepo extends RdbmsCentralRepo {
|
||||
private PostgresCentralRepo() throws CentralRepoException {
|
||||
dbSettings = new PostgresCentralRepoSettings();
|
||||
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
|
||||
|
||||
this.updateExaminers();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,7 +51,7 @@ import org.sleuthkit.autopsy.healthmonitor.HealthMonitor;
|
||||
import org.sleuthkit.autopsy.healthmonitor.TimingMetric;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber;
|
||||
import org.sleuthkit.datamodel.Examiner;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
@ -102,8 +102,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
// Update Test code if this changes. It's hard coded there.
|
||||
static final int DEFAULT_BULK_THRESHHOLD = 1000;
|
||||
|
||||
private Examiner cachedCurrentExaminer = null;
|
||||
|
||||
private static final int QUERY_STR_MAX_LEN = 1000;
|
||||
|
||||
|
||||
@ -222,7 +220,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
/**
|
||||
* Reset the contents of the caches associated with EamDb results.
|
||||
*/
|
||||
@Override
|
||||
public final void clearCaches() {
|
||||
synchronized(typeCache) {
|
||||
typeCache.invalidateAll();
|
||||
@ -233,7 +230,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
dataSourceCacheByDsObjectId.invalidateAll();
|
||||
dataSourceCacheById.invalidateAll();
|
||||
accountsCache.invalidateAll();
|
||||
cachedCurrentExaminer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2520,72 +2516,6 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the examiners table, by adding current logged in user to
|
||||
* examiners table, if not already in there.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void updateExaminers() throws CentralRepoException {
|
||||
|
||||
String loginName = System.getProperty("user.name");
|
||||
if (loginName.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "Cannot determine logged in user name");
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection connection = connect();
|
||||
Statement statement = connection.createStatement();) {
|
||||
|
||||
String insertSQL;
|
||||
switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
|
||||
case POSTGRESQL:
|
||||
insertSQL = "INSERT INTO examiners (login_name) VALUES ('" + loginName + "')" + getConflictClause(); //NON-NLS
|
||||
break;
|
||||
case SQLITE:
|
||||
insertSQL = "INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + loginName + "')";
|
||||
break;
|
||||
default:
|
||||
throw new CentralRepoException(String.format("Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform()));
|
||||
}
|
||||
statement.execute(insertSQL); //NON-NLS
|
||||
} catch (SQLException ex) {
|
||||
throw new CentralRepoException("Error inserting row in examiners", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Examiner getCurrentCentralRepoExaminer() throws CentralRepoException {
|
||||
|
||||
// return cached value if there's one
|
||||
if (cachedCurrentExaminer != null) {
|
||||
return cachedCurrentExaminer;
|
||||
}
|
||||
String loginName = System.getProperty("user.name");
|
||||
if (loginName == null || loginName.isEmpty()) {
|
||||
throw new CentralRepoException("Failed to determine logged in user name.");
|
||||
}
|
||||
|
||||
String querySQL = "SELECT * FROM examiners WHERE login_name = '" + loginName + "'";
|
||||
|
||||
try (Connection connection = connect();
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(querySQL);) {
|
||||
|
||||
if (resultSet.next()) {
|
||||
cachedCurrentExaminer = new Examiner(resultSet.getLong("id"), resultSet.getString("login_name"), resultSet.getString("display_name"));
|
||||
return cachedCurrentExaminer;
|
||||
} else {
|
||||
throw new CentralRepoException("Error getting examiner for name = " + loginName);
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
throw new CentralRepoException("Error getting examiner for name = " + loginName, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeInsertSQL(String insertClause) throws CentralRepoException {
|
||||
|
||||
@ -2766,6 +2696,61 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the examiner table for the given user name.
|
||||
* Adds a row if the user is not found in the examiner table.
|
||||
*
|
||||
* @param examinerLoginName user name to look for.
|
||||
* @return CentralRepoExaminer for the given user name.
|
||||
* @throws CentralRepoException If there is an error in looking up or
|
||||
* inserting the user in the examiners table.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public CentralRepoExaminer getOrInsertExaminer(String examinerLoginName) throws CentralRepoException {
|
||||
|
||||
String querySQL = "SELECT * FROM examiners WHERE login_name = '" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) + "'";
|
||||
try (Connection connection = connect();
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(querySQL);) {
|
||||
|
||||
if (resultSet.next()) {
|
||||
return new CentralRepoExaminer(resultSet.getLong("id"), resultSet.getString("login_name"));
|
||||
} else {
|
||||
// Could not find this user in the Examiner table, add a row for it.
|
||||
try {
|
||||
String insertSQL;
|
||||
switch (CentralRepoDbManager.getSavedDbChoice().getDbPlatform()) {
|
||||
case POSTGRESQL:
|
||||
insertSQL = "INSERT INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) + "')" + getConflictClause(); //NON-NLS
|
||||
break;
|
||||
case SQLITE:
|
||||
insertSQL = "INSERT OR IGNORE INTO examiners (login_name) VALUES ('" + SleuthkitCase.escapeSingleQuotes(examinerLoginName) + "')"; //NON-NLS
|
||||
break;
|
||||
default:
|
||||
throw new CentralRepoException(String.format("Cannot add examiner to currently selected CR database platform %s", CentralRepoDbManager.getSavedDbChoice().getDbPlatform())); //NON-NLS
|
||||
}
|
||||
statement.execute(insertSQL);
|
||||
|
||||
// Query the table again to get the row for the user
|
||||
try (ResultSet resultSet2 = statement.executeQuery(querySQL)) {
|
||||
if (resultSet2.next()) {
|
||||
return new CentralRepoExaminer(resultSet2.getLong("id"), resultSet2.getString("login_name"));
|
||||
} else {
|
||||
throw new CentralRepoException("Error getting examiner for name = " + examinerLoginName);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
throw new CentralRepoException("Error inserting row in examiners", ex);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
throw new CentralRepoException("Error getting examiner for name = " + examinerLoginName, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing organization.
|
||||
*
|
||||
|
@ -78,8 +78,6 @@ final class SqliteCentralRepo extends RdbmsCentralRepo {
|
||||
private SqliteCentralRepo() throws CentralRepoException {
|
||||
dbSettings = new SqliteCentralRepoSettings();
|
||||
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
|
||||
|
||||
this.updateExaminers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -855,15 +853,6 @@ final class SqliteCentralRepo extends RdbmsCentralRepo {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateExaminers() throws CentralRepoException {
|
||||
try {
|
||||
acquireSharedLock();
|
||||
super.updateExaminers();
|
||||
} finally {
|
||||
releaseSharedLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a reference set with the given name/version is in the
|
||||
|
@ -17,7 +17,10 @@ ContextViewer.messageFrom=From
|
||||
ContextViewer.messageOn=On
|
||||
ContextViewer.messageTo=To
|
||||
ContextViewer.on=Opened at
|
||||
ContextViewer.programExecution=Program Execution:
|
||||
ContextViewer.recentDocs=Recent Documents:
|
||||
ContextViewer.runOn=Program Run On
|
||||
ContextViewer.runUnknown=\ Program Run at unknown time
|
||||
ContextViewer.title=Context
|
||||
ContextViewer.toolTip=Displays context for selected file.
|
||||
ContextViewer.unknown=Opened at unknown time
|
||||
|
@ -334,7 +334,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
||||
@NbBundle.Messages({
|
||||
"ContextViewer.attachmentSource=Attached to: ",
|
||||
"ContextViewer.downloadSource=Downloaded from: ",
|
||||
"ContextViewer.recentDocs=Recent Documents: "
|
||||
"ContextViewer.recentDocs=Recent Documents: ",
|
||||
"ContextViewer.programExecution=Program Execution: "
|
||||
})
|
||||
private void setSourceFields(BlackboardArtifact associatedArtifact) throws TskCoreException {
|
||||
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
|
||||
@ -357,6 +358,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
||||
javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact);
|
||||
contextUsagePanels.add(usagePanel);
|
||||
|
||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
||||
String sourceName = Bundle.ContextViewer_programExecution();
|
||||
String sourceText = programExecArtifactToString(associatedArtifact);
|
||||
javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact);
|
||||
contextUsagePanels.add(usagePanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,6 +422,36 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a display string with Program Execution
|
||||
* artifact.
|
||||
*
|
||||
* @param artifact artifact to get doc from.
|
||||
*
|
||||
* @return Display string with download URL and date/time.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"ContextViewer.runOn=Program Run On",
|
||||
"ContextViewer.runUnknown= Program Run at unknown time"
|
||||
})
|
||||
private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
|
||||
StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
|
||||
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
|
||||
|
||||
BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||
|
||||
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
|
||||
if (attribute != null && attribute.getValueLong() > 0) {
|
||||
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
|
||||
} else {
|
||||
sb.append(Bundle.ContextViewer_runUnknown());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a abbreviated display string for a message artifact.
|
||||
*
|
||||
|
@ -42,9 +42,9 @@ public final class AutopsyEventPublisher {
|
||||
private static final Logger logger = Logger.getLogger(AutopsyEventPublisher.class.getName());
|
||||
private static final int MAX_REMOTE_EVENT_PUBLISH_TRIES = 1;
|
||||
private final LocalEventPublisher localPublisher; // LocalEventPublisher is thread-safe
|
||||
@GuardedBy("this)")
|
||||
@GuardedBy("this")
|
||||
private RemoteEventPublisher remotePublisher;
|
||||
@GuardedBy("this)")
|
||||
@GuardedBy("this")
|
||||
private String currentChannelName;
|
||||
|
||||
/**
|
||||
|
@ -165,13 +165,8 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
Assert.fail("Failed to create central repo database, should be located at + " + crDbFilePath);
|
||||
}
|
||||
|
||||
// clear caches to match the clean slate database.
|
||||
CentralRepository.getInstance().clearCaches();
|
||||
|
||||
// Add current logged in user to examiners table - since we delete the DB after every test.
|
||||
CentralRepository.getInstance().updateExaminers();
|
||||
|
||||
// Set up some default objects to be used by the tests
|
||||
// Set up some default objects to be used by the tests
|
||||
try {
|
||||
case1 = new CorrelationCase(CASE_1_UUID, "case1");
|
||||
case1 = CentralRepository.getInstance().newCase(case1);
|
||||
@ -304,6 +299,9 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
Assert.assertEquals(DOG_PERSONA_NAME, pa1.getPersona().getName());
|
||||
Assert.assertEquals(status.name(), dogPersona.getStatus().name());
|
||||
Assert.assertTrue(dogPersona.getExaminer().getLoginName().equalsIgnoreCase(pa1.getExaminer().getLoginName()));
|
||||
|
||||
// Assert that the persona was created by the currently logged in user
|
||||
Assert.assertTrue(dogPersona.getExaminer().getLoginName().equalsIgnoreCase(System.getProperty("user.name")));
|
||||
|
||||
// Assert that Persona was created within the last 10 mins
|
||||
Assert.assertTrue(Instant.now().toEpochMilli() - pa1.getDateAdded() < 600 * 1000);
|
||||
@ -371,7 +369,7 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
|
||||
|
||||
// Get ALL personas for an account
|
||||
Collection<PersonaAccount> personaAccounts2 = Persona.getPersonaAccountsForAccount(catdogFBAccount.getAccountId());
|
||||
Collection<PersonaAccount> personaAccounts2 = PersonaAccount.getPersonaAccountsForAccount(catdogFBAccount.getAccountId());
|
||||
|
||||
Assert.assertEquals(2, personaAccounts2.size());
|
||||
for (PersonaAccount pa: personaAccounts2) {
|
||||
@ -525,21 +523,21 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
|
||||
|
||||
|
||||
Collection<CentralRepoAccount> dogAccounts = dogPersona.getAccounts();
|
||||
Assert.assertEquals(2, dogAccounts.size()); // Dog has 2 accounts.
|
||||
for (CentralRepoAccount acct : dogAccounts) {
|
||||
Assert.assertTrue(acct.getTypeSpecificId().equalsIgnoreCase(FACEBOOK_ID_CATDOG)
|
||||
|| acct.getTypeSpecificId().equalsIgnoreCase(DOG_EMAIL_ID));
|
||||
Collection<PersonaAccount> dogPersonaAccounts = dogPersona.getPersonaAccounts();
|
||||
Assert.assertEquals(2, dogPersonaAccounts.size()); // Dog has 2 accounts.
|
||||
for (PersonaAccount pa : dogPersonaAccounts) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().equalsIgnoreCase(FACEBOOK_ID_CATDOG)
|
||||
|| pa.getAccount().getTypeSpecificId().equalsIgnoreCase(DOG_EMAIL_ID));
|
||||
// System.out.println("Dog Account id : " + acct.getTypeSpecificId());
|
||||
}
|
||||
|
||||
|
||||
Collection<CentralRepoAccount> catAccounts = catPersona.getAccounts();
|
||||
Assert.assertEquals(2, catAccounts.size()); // cat has 2 accounts.
|
||||
for (CentralRepoAccount acct:catAccounts) {
|
||||
Collection<PersonaAccount> catPersonaAccounts = catPersona.getPersonaAccounts();
|
||||
Assert.assertEquals(2, catPersonaAccounts.size()); // cat has 2 accounts.
|
||||
for (PersonaAccount pa:catPersonaAccounts) {
|
||||
//System.out.println("Cat Account id : " + acct.getTypeSpecificId());
|
||||
Assert.assertTrue(acct.getTypeSpecificId().equalsIgnoreCase(FACEBOOK_ID_CATDOG)
|
||||
|| acct.getTypeSpecificId().equalsIgnoreCase(CAT_WHATSAPP_ID));
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().equalsIgnoreCase(FACEBOOK_ID_CATDOG)
|
||||
|| pa.getAccount().getTypeSpecificId().equalsIgnoreCase(CAT_WHATSAPP_ID));
|
||||
}
|
||||
|
||||
// create account and Persona for Sherlock Holmes.
|
||||
@ -644,22 +642,22 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
// Test getting peronas by data source.
|
||||
|
||||
// Test that getting all Personas for DS 1
|
||||
Collection<Persona> ds1Persona = Persona.getPersonaForDataSource(dataSource1fromCase1);
|
||||
Collection<Persona> ds1Persona = Persona.getPersonasForDataSource(dataSource1fromCase1);
|
||||
Assert.assertEquals(2, ds1Persona.size()); //
|
||||
|
||||
Collection<Persona> ds2Persona = Persona.getPersonaForDataSource(dataSource2fromCase1);
|
||||
Collection<Persona> ds2Persona = Persona.getPersonasForDataSource(dataSource2fromCase1);
|
||||
Assert.assertEquals(2, ds2Persona.size()); //
|
||||
|
||||
Collection<Persona> ds3Persona = Persona.getPersonaForDataSource(dataSource1fromCase2);
|
||||
Collection<Persona> ds3Persona = Persona.getPersonasForDataSource(dataSource1fromCase2);
|
||||
Assert.assertEquals(2, ds3Persona.size()); //
|
||||
|
||||
Collection<Persona> ds4Persona = Persona.getPersonaForDataSource(dataSource1fromCase3);
|
||||
Collection<Persona> ds4Persona = Persona.getPersonasForDataSource(dataSource1fromCase3);
|
||||
Assert.assertEquals(1, ds4Persona.size()); //
|
||||
|
||||
Collection<Persona> ds5Persona = Persona.getPersonaForDataSource(dataSource2fromCase3);
|
||||
Collection<Persona> ds5Persona = Persona.getPersonasForDataSource(dataSource2fromCase3);
|
||||
Assert.assertEquals(0, ds5Persona.size()); //
|
||||
|
||||
Collection<Persona> ds6Persona = Persona.getPersonaForDataSource(dataSource1fromCase4);
|
||||
Collection<Persona> ds6Persona = Persona.getPersonasForDataSource(dataSource1fromCase4);
|
||||
Assert.assertEquals(0, ds6Persona.size()); //
|
||||
|
||||
|
||||
@ -687,7 +685,7 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "The person lost his name", Persona.Confidence.LOW);
|
||||
|
||||
// Verify Persona has a default name
|
||||
Assert.assertEquals("NoName", pa1.getPersona().getName());
|
||||
Assert.assertEquals("Unknown", pa1.getPersona().getName());
|
||||
|
||||
} catch (CentralRepoException ex) {
|
||||
Assert.fail("No name persona test failed. Exception: " + ex);
|
||||
@ -695,5 +693,212 @@ public class CentralRepoPersonasTest extends TestCase {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests searching of Persona by persona name.
|
||||
*/
|
||||
public void testPersonaSearchByName() {
|
||||
|
||||
// Test1: create Personas with similar names.
|
||||
{
|
||||
try {
|
||||
// Create an email account
|
||||
CentralRepoAccount emailAccount1 = CentralRepository.getInstance()
|
||||
.getOrCreateAccount(emailAccountType, EMAIL_ID_1);
|
||||
|
||||
// Create all personas with same comment.
|
||||
final String personaComment = "Creator of Jungle Book.";
|
||||
|
||||
// Create a Persona with name "Rudyard Kipling"
|
||||
Persona.createPersonaForAccount("Rudyard Kipling", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
// Create a Persona with name "Rudy"
|
||||
Persona.createPersonaForAccount("Rudy", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
|
||||
// Create a Persona with name "Kipling Senior"
|
||||
Persona.createPersonaForAccount("Kipling Senior", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
// Create a Persona with name "Senor Kipling"
|
||||
Persona.createPersonaForAccount("Senor Kipling", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
|
||||
// Test 1 Search "kipling" - expect 3 matches
|
||||
Collection<Persona> personaSearchResult = Persona.getPersonaByName("kipling");
|
||||
Assert.assertEquals(3, personaSearchResult.size());
|
||||
for (Persona p: personaSearchResult) {
|
||||
Assert.assertTrue(p.getComment().equalsIgnoreCase(personaComment));
|
||||
}
|
||||
|
||||
// Search 'Rudy' - expect 2 matches
|
||||
personaSearchResult = Persona.getPersonaByName("Rudy");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
|
||||
|
||||
// Search 'Sen' - expect 2 matches
|
||||
personaSearchResult = Persona.getPersonaByName("Sen");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
|
||||
|
||||
// Search 'IPL' - expect 3 matches
|
||||
personaSearchResult = Persona.getPersonaByName("IPL");
|
||||
Assert.assertEquals(3, personaSearchResult.size());
|
||||
|
||||
|
||||
// Serach "Rudyard Kipling" - expect 1 match
|
||||
personaSearchResult = Persona.getPersonaByName("Rudyard Kipling");
|
||||
Assert.assertEquals(1, personaSearchResult.size());
|
||||
Assert.assertTrue(personaSearchResult.iterator().next().getName().equalsIgnoreCase("Rudyard Kipling"));
|
||||
|
||||
// Search '' - expect ALL (4) to match
|
||||
personaSearchResult = Persona.getPersonaByName("");
|
||||
Assert.assertEquals(4, personaSearchResult.size());
|
||||
|
||||
|
||||
} catch (CentralRepoException ex) {
|
||||
Assert.fail("No name persona test failed. Exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests searching of Persona by account identifier substrings.
|
||||
*/
|
||||
public void testPersonaSearchByAccountIdentifier() {
|
||||
|
||||
// Test1: create Personas with similar names.
|
||||
{
|
||||
try {
|
||||
// Create an email account1
|
||||
CentralRepoAccount emailAccount1 = CentralRepository.getInstance()
|
||||
.getOrCreateAccount(emailAccountType, "joeexotic555@yahoo.com");
|
||||
|
||||
// Create all personas with same comment.
|
||||
final String personaComment = "Comment used to create a persona";
|
||||
|
||||
// Create a Persona with name "Joe Exotic" associated with the email address
|
||||
Persona.createPersonaForAccount("Joe Exotic", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
// Create a Persona with name "Tiger King" associated with the email address
|
||||
Persona.createPersonaForAccount("Tiger King", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
|
||||
|
||||
// Create an phone account with number "+1 999 555 3366"
|
||||
CentralRepoAccount phoneAccount1 = CentralRepository.getInstance()
|
||||
.getOrCreateAccount(phoneAccountType, "+1 999 555 3366");
|
||||
|
||||
|
||||
// Create a Persona with name "Carol Baskin" associated
|
||||
Persona.createPersonaForAccount("Carol Baskin", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, phoneAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
// Create a Persona with no name assoctaed with
|
||||
Persona.createPersonaForAccount(null, personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, phoneAccount1, "", Persona.Confidence.LOW);
|
||||
|
||||
|
||||
|
||||
// Create another email account1
|
||||
CentralRepoAccount emailAccount2 = CentralRepository.getInstance()
|
||||
.getOrCreateAccount(emailAccountType, "jodoe@mail.com");
|
||||
|
||||
|
||||
|
||||
// Create a Persona with name "John Doe" associated with the email address
|
||||
Persona.createPersonaForAccount("John Doe", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount2, "", Persona.Confidence.LOW);
|
||||
|
||||
Persona.createPersonaForAccount("Joanne Doe", personaComment,
|
||||
Persona.PersonaStatus.ACTIVE, emailAccount2, "", Persona.Confidence.LOW);
|
||||
|
||||
|
||||
|
||||
// Test1 Search on 'joe' - should get 2
|
||||
Collection<PersonaAccount> personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("joe");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("joe"));
|
||||
}
|
||||
|
||||
// Search on 'exotic' - should get 2
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("exotic");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("exotic"));
|
||||
}
|
||||
|
||||
// Test1 Search on '999' - should get 2
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("999");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("999"));
|
||||
}
|
||||
|
||||
// Test1 Search on '555' - should get 4
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("555");
|
||||
Assert.assertEquals(4, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("555"));
|
||||
}
|
||||
|
||||
// Test1 Search on 'doe' - should get 2
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("doe");
|
||||
Assert.assertEquals(2, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("doe"));
|
||||
}
|
||||
|
||||
// Test1 Search on '@' - should get 4
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("@");
|
||||
Assert.assertEquals(4, personaSearchResult.size());
|
||||
for (PersonaAccount pa: personaSearchResult) {
|
||||
Assert.assertTrue(pa.getAccount().getTypeSpecificId().contains("@"));
|
||||
}
|
||||
|
||||
// Test1 Search on '' - should get ALL (6)
|
||||
personaSearchResult = PersonaAccount.getPersonaAccountsForAccountIdentifier("");
|
||||
Assert.assertEquals(6, personaSearchResult.size());
|
||||
|
||||
|
||||
} catch (CentralRepoException ex) {
|
||||
Assert.fail("No name persona test failed. Exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getOrInsertExaminer() api.
|
||||
*/
|
||||
public void testExaminers() {
|
||||
|
||||
try {
|
||||
String examinerName = "abcdefg";
|
||||
CentralRepoExaminer examiner = CentralRepository.getInstance().getOrInsertExaminer(examinerName);
|
||||
Assert.assertTrue(examiner.getLoginName().equalsIgnoreCase(examinerName));
|
||||
|
||||
examinerName = "";
|
||||
examiner = CentralRepository.getInstance().getOrInsertExaminer(examinerName);
|
||||
Assert.assertTrue(examiner.getLoginName().equalsIgnoreCase(examinerName));
|
||||
|
||||
examinerName = "D'Aboville";
|
||||
examiner = CentralRepository.getInstance().getOrInsertExaminer(examinerName);
|
||||
Assert.assertTrue(examiner.getLoginName().equalsIgnoreCase(examinerName));
|
||||
|
||||
} catch (CentralRepoException ex) {
|
||||
Assert.fail("Examiner tests failed. Exception: " + ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,9 @@
|
||||
<copy todir="${basedir}/release/ESEDatabaseView" >
|
||||
<fileset dir="${thirdparty.dir}/ESEDatabaseView/" />
|
||||
</copy>
|
||||
<copy todir="${basedir}/release/markmckinnon/" >
|
||||
<fileset dir="${thirdparty.dir}/markmckinnon/" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
||||
|
@ -55,6 +55,13 @@ ExtractSafari_Error_Getting_History=An error occurred while processing Safari hi
|
||||
ExtractSafari_Error_Parsing_Bookmark=An error occured while processing Safari Bookmark files
|
||||
ExtractSafari_Error_Parsing_Cookies=An error occured while processing Safari Cookies files
|
||||
ExtractSafari_Module_Name=Safari
|
||||
ExtractSru_error_finding_export_srudb_program=Error finding export_srudb program
|
||||
ExtractSru_module_name=System Resource Usage Extractor
|
||||
ExtractSru_process_error_executing_export_srudb_program=Error running export_srudb program
|
||||
ExtractSru_process_errormsg_find_software_hive=Unable to find SOFTWARE HIVE file
|
||||
ExtractSru_process_errormsg_find_srudb_dat=Unable to find srudb.dat file
|
||||
ExtractSru_process_errormsg_write_software_hive=Unable to write SOFTWARE HIVE file
|
||||
ExtractSru_process_errormsg_write_srudb_dat=Unable to write srudb.dat file
|
||||
ExtractZone_Internet=Internet Zone
|
||||
ExtractZone_Local_Intranet=Local Intranet Zone
|
||||
ExtractZone_Local_Machine=Local Machine Zone
|
||||
|
@ -0,0 +1,484 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
*
|
||||
* 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.autopsy.recentactivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.openide.modules.InstalledFileLocator;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Extract the System Resource Usage database to a temp directory so it can be parsed into a SQLite db
|
||||
* and then brought into extracted content
|
||||
*/
|
||||
final class ExtractSru extends Extract {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExtractSru.class.getName());
|
||||
|
||||
private IngestJobContext context;
|
||||
|
||||
private static final String APPLICATION_USAGE_SOURCE_NAME = "System Resource Usage - Application Usage"; //NON-NLS
|
||||
private static final String NETWORK_USAGE_SOURCE_NAME = "System Resource Usage - Network Usage";
|
||||
|
||||
// private static final String ARTIFACT_ATTRIBUTE_NAME = "TSK_ARTIFACT_NAME"; //NON-NLS
|
||||
|
||||
private static final String MODULE_NAME = "extractSRU"; //NON-NLS
|
||||
|
||||
private static final String SRU_TOOL_FOLDER = "markmckinnon"; //NON-NLS
|
||||
private static final String SRU_TOOL_NAME_WINDOWS_32 = "Export_Srudb_32.exe"; //NON-NLS
|
||||
private static final String SRU_TOOL_NAME_WINDOWS_64 = "Export_Srudb_64.exe"; //NON-NLS
|
||||
private static final String SRU_TOOL_NAME_LINUX = "Export_Srudb_Linux.exe"; //NON-NLS
|
||||
private static final String SRU_TOOL_NAME_MAC = "Export_srudb_macos"; //NON-NLS
|
||||
private static final String SRU_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
|
||||
private static final String SRU_ERROR_FILE_NAME = "Error.txt"; //NON-NLS
|
||||
|
||||
private static final Map<String, AbstractFile> applicationFilesFound = new HashMap<>();
|
||||
|
||||
@Messages({
|
||||
"ExtractSru_module_name=System Resource Usage Extractor"
|
||||
})
|
||||
ExtractSru() {
|
||||
this.moduleName = Bundle.ExtractSru_module_name();
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"ExtractSru_error_finding_export_srudb_program=Error finding export_srudb program",
|
||||
"ExtractSru_process_error_executing_export_srudb_program=Error running export_srudb program"
|
||||
})
|
||||
|
||||
@Override
|
||||
void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
|
||||
|
||||
this.context = context;
|
||||
|
||||
String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + "sru";
|
||||
File dir = new File(modOutPath);
|
||||
if (dir.exists() == false) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "sru"); //NON-NLS
|
||||
String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath);
|
||||
|
||||
if (softwareHiveFileName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractFile sruAbstractFile = getSruFile(dataSource, tempDirPath);
|
||||
|
||||
String sruFileName = tempDirPath + File.separator + sruAbstractFile.getId() + "_" + sruAbstractFile.getName();
|
||||
|
||||
if (sruFileName == null) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_srudb_dat());
|
||||
logger.log(Level.SEVERE, "SRUDB.dat file not found"); //NON-NLS
|
||||
return; //If we cannot find the srudb.dat file we cannot proceed
|
||||
}
|
||||
|
||||
final String sruDumper = getPathForSruDumper();
|
||||
if (sruDumper == null) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_error_finding_export_srudb_program());
|
||||
logger.log(Level.SEVERE, "Error finding export_srudb program"); //NON-NLS
|
||||
return; //If we cannot find the export_srudb program we cannot proceed
|
||||
}
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String modOutFile = modOutPath + File.separator + sruAbstractFile.getId() + "_srudb.db3";
|
||||
|
||||
extractSruFiles(sruDumper, sruFileName, modOutFile, tempDirPath, softwareHiveFileName);
|
||||
|
||||
findSruExecutedFiles(modOutFile, dataSource);
|
||||
|
||||
createNetUsageArtifacts(modOutFile, sruAbstractFile);
|
||||
createAppUsageArtifacts(modOutFile, sruAbstractFile);
|
||||
} catch (IOException ex) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_error_executing_export_srudb_program());
|
||||
logger.log(Level.SEVERE, "SRUDB.dat file not found"); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"ExtractSru_process_errormsg_find_software_hive=Unable to find SOFTWARE HIVE file",
|
||||
"ExtractSru_process_errormsg_write_software_hive=Unable to write SOFTWARE HIVE file"
|
||||
})
|
||||
|
||||
/**
|
||||
* Extract the SOFTWARE hive file to the temp directory
|
||||
*
|
||||
* @param dataSource datasource where software hiive is
|
||||
* @param tempDirPath temp directory to write file to
|
||||
*
|
||||
* @return Software hive file location
|
||||
*/
|
||||
String getSoftwareHiveFile(Content dataSource, String tempDirPath) {
|
||||
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
|
||||
|
||||
List<AbstractFile> softwareHiveFiles;
|
||||
|
||||
try {
|
||||
softwareHiveFiles = fileManager.findFiles(dataSource, "SOFTWARE"); //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive());
|
||||
logger.log(Level.WARNING, "Unable to find SOFTWARE HIVE file.", ex); //NON-NLS
|
||||
return null; // No need to continue
|
||||
}
|
||||
|
||||
String softwareHiveFileName = null;
|
||||
|
||||
for (AbstractFile softwareFile : softwareHiveFiles) {
|
||||
|
||||
if (softwareFile.getParentPath().endsWith("/config/")) {
|
||||
softwareHiveFileName = tempDirPath + File.separator + softwareFile.getId() + "_" + softwareFile.getName();
|
||||
|
||||
try {
|
||||
ContentUtils.writeToFile(softwareFile, new File(softwareHiveFileName));
|
||||
} catch (IOException ex) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive());
|
||||
logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", softwareFile.getName(), softwareFile), ex); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return softwareHiveFileName;
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"ExtractSru_process_errormsg_find_srudb_dat=Unable to find srudb.dat file",
|
||||
"ExtractSru_process_errormsg_write_srudb_dat=Unable to write srudb.dat file"
|
||||
})
|
||||
/**
|
||||
* Extract the SOFTWARE hive file to the temp directory
|
||||
*
|
||||
* @param dataSource datasource where software hiive is
|
||||
* @param tempDirPath temp directory to write file to
|
||||
*
|
||||
* @return Software hive file location
|
||||
*/
|
||||
AbstractFile getSruFile(Content dataSource, String tempDirPath) {
|
||||
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
|
||||
|
||||
List<AbstractFile> sruFiles;
|
||||
|
||||
try {
|
||||
sruFiles = fileManager.findFiles(dataSource, "SRUDB.DAT"); //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_srudb_dat());
|
||||
logger.log(Level.WARNING, "Unable to find SRUDB.DAT file.", ex); //NON-NLS
|
||||
return null; // No need to continue
|
||||
}
|
||||
|
||||
AbstractFile sruAbstractFile = null;
|
||||
|
||||
for (AbstractFile sruFile : sruFiles) {
|
||||
|
||||
String sruFileName = tempDirPath + File.separator + sruFile.getId() + "_" + sruFile.getName();
|
||||
sruAbstractFile = sruFile;
|
||||
|
||||
try {
|
||||
ContentUtils.writeToFile(sruFile, new File(sruFileName));
|
||||
} catch (IOException ex) {
|
||||
this.addErrorMessage(Bundle.ExtractSru_process_errormsg_write_srudb_dat());
|
||||
logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", sruFile.getName(), sruFile), ex); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
return sruAbstractFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the export srudb program against the srudb.dat file
|
||||
*
|
||||
* @param sruExePath
|
||||
* @param tempDirPath
|
||||
* @param tempOutPath
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
void extractSruFiles(String sruExePath, String sruFile, String tempOutFile, String tempOutPath, String softwareHiveFile) throws IOException {
|
||||
final Path outputFilePath = Paths.get(tempOutPath, SRU_OUTPUT_FILE_NAME);
|
||||
final Path errFilePath = Paths.get(tempOutPath, SRU_ERROR_FILE_NAME);
|
||||
|
||||
List<String> commandLine = new ArrayList<>();
|
||||
commandLine.add(sruExePath);
|
||||
commandLine.add(sruFile); //NON-NLS
|
||||
commandLine.add(softwareHiveFile);
|
||||
commandLine.add(tempOutFile);
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||
processBuilder.redirectOutput(outputFilePath.toFile());
|
||||
processBuilder.redirectError(errFilePath.toFile());
|
||||
|
||||
ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
|
||||
}
|
||||
|
||||
private String getPathForSruDumper() {
|
||||
Path path = null;
|
||||
if (PlatformUtil.isWindowsOS()) {
|
||||
if (PlatformUtil.is64BitOS()) {
|
||||
path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_64);
|
||||
} else {
|
||||
path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_32);
|
||||
}
|
||||
} else {
|
||||
if ("Linux".equals(PlatformUtil.getOSName())) {
|
||||
path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_LINUX);
|
||||
} else {
|
||||
path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_MAC);
|
||||
}
|
||||
}
|
||||
File sruToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
|
||||
ExtractSru.class.getPackage().getName(), false);
|
||||
if (sruToolFile != null) {
|
||||
return sruToolFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void findSruExecutedFiles(String sruDb, Content dataSource) {
|
||||
|
||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
||||
|
||||
String sqlStatement = "SELECT DISTINCT SUBSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), INSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), '\\')) "
|
||||
+ " application_name, idBlob source_name FROM SruDbIdMapTable WHERE idType = 0 AND idBlob NOT LIKE '!!%'"; //NON-NLS
|
||||
|
||||
try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
|
||||
ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
|
||||
|
||||
while (resultSet.next()) {
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Cancelled SRU Artifact Creation."); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
String applicationName = resultSet.getString("application_name"); //NON-NLS
|
||||
String sourceName = resultSet.getString("source_name"); //NON-NLS
|
||||
|
||||
String normalizePathName = FilenameUtils.normalize(applicationName, true);
|
||||
String fileName = FilenameUtils.getName(normalizePathName);
|
||||
String filePath = FilenameUtils.getPath(normalizePathName);
|
||||
if (fileName.contains(" [")) {
|
||||
fileName = fileName.substring(0, fileName.indexOf(" ["));
|
||||
}
|
||||
List<AbstractFile> sourceFiles;
|
||||
try {
|
||||
sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
|
||||
for (AbstractFile sourceFile : sourceFiles) {
|
||||
if (sourceFile.getParentPath().endsWith(filePath)) {
|
||||
applicationFilesFound.put(sourceName.toLowerCase(), sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, String.format("Error finding actual file %s. file may not exist", normalizePathName)); //NON-NLS
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Error while trying to read into a sqlite db.", ex);//NON-NLS
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createNetUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
|
||||
List<BlackboardArtifact> bba = new ArrayList<>();
|
||||
|
||||
String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name, "
|
||||
+ " bytesSent, BytesRecvd FROM network_Usage , SruDbIdMapTable "
|
||||
+ " where appId = IdIndex and IdType = 0 order by ExecutionTime;"; //NON-NLS
|
||||
|
||||
try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
|
||||
ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
|
||||
|
||||
while (resultSet.next()) {
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
String applicationName = resultSet.getString("Application_Name"); //NON-NLS
|
||||
Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS
|
||||
Long bytesSent = Long.valueOf(resultSet.getInt("bytesSent")); //NON-NLS
|
||||
Long bytesRecvd = Long.valueOf(resultSet.getInt("BytesRecvd")); //NON-NLS
|
||||
String userName = resultSet.getString("User_Name"); //NON-NLS
|
||||
|
||||
Collection<BlackboardAttribute> bbattributes = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
|
||||
applicationName),//NON-NLS
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
|
||||
userName),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
|
||||
executionTime),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_SENT, getName(), bytesSent),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_RECEIVED, getName(), bytesRecvd),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), NETWORK_USAGE_SOURCE_NAME));
|
||||
|
||||
try {
|
||||
BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
|
||||
bbart.addAttributes(bbattributes);
|
||||
bba.add(bbart);
|
||||
BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
|
||||
if (associateBbArtifact != null) {
|
||||
bba.add(associateBbArtifact);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
|
||||
}
|
||||
|
||||
try {
|
||||
blackboard.postArtifacts(bba, MODULE_NAME);
|
||||
} catch (Blackboard.BlackboardException ex) {
|
||||
logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
private void createAppUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
|
||||
List<BlackboardArtifact> bba = new ArrayList<>();
|
||||
|
||||
String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name "
|
||||
+ " FROM Application_Resource_Usage, SruDbIdMapTable WHERE "
|
||||
+ " idType = 0 and idIndex = appId order by ExecutionTime;"; //NON-NLS
|
||||
|
||||
try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
|
||||
ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
|
||||
|
||||
while (resultSet.next()) {
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
String applicationName = resultSet.getString("Application_Name"); //NON-NLS
|
||||
Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS
|
||||
String userName = resultSet.getString("User_Name");
|
||||
|
||||
Collection<BlackboardAttribute> bbattributes = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
|
||||
applicationName),//NON-NLS
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
|
||||
userName),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
|
||||
executionTime),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), APPLICATION_USAGE_SOURCE_NAME));
|
||||
|
||||
try {
|
||||
BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
|
||||
bbart.addAttributes(bbattributes);
|
||||
bba.add(bbart);
|
||||
BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
|
||||
if (associateBbArtifact != null) {
|
||||
bba.add(associateBbArtifact);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
|
||||
}
|
||||
|
||||
try {
|
||||
blackboard.postArtifacts(bba, MODULE_NAME);
|
||||
} catch (Blackboard.BlackboardException ex) {
|
||||
logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create associated artifacts using file path name and the artifact it associates with
|
||||
*
|
||||
* @param filePathName file and path of object being associated with
|
||||
*
|
||||
* @param bba blackboard artifact to associate with
|
||||
*
|
||||
* @returnv BlackboardArtifact or a null value
|
||||
*/
|
||||
private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
|
||||
if (applicationFilesFound.containsKey(filePathName)) {
|
||||
AbstractFile sourceFile = applicationFilesFound.get(filePathName);
|
||||
Collection<BlackboardAttribute> bbattributes2 = new ArrayList<>();
|
||||
bbattributes2.addAll(Arrays.asList(
|
||||
new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT, this.getName(),
|
||||
bba.getArtifactID())));
|
||||
|
||||
BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2);
|
||||
if (associatedObjectBba != null) {
|
||||
return associatedObjectBba;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -78,6 +78,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
Extract safari = new ExtractSafari();
|
||||
Extract zoneInfo = new ExtractZoneIdentifier();
|
||||
Extract recycleBin = new ExtractRecycleBin();
|
||||
Extract sru = new ExtractSru();
|
||||
|
||||
extractors.add(chrome);
|
||||
extractors.add(firefox);
|
||||
@ -91,7 +92,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
extractors.add(dataSourceAnalyzer); //this needs to run after ExtractRegistry and ExtractOs
|
||||
extractors.add(zoneInfo); // this needs to run after the web browser modules
|
||||
extractors.add(recycleBin); // this needs to run after ExtractRegistry and ExtractOS
|
||||
|
||||
extractors.add(sru);
|
||||
|
||||
browserExtractors.add(chrome);
|
||||
browserExtractors.add(firefox);
|
||||
browserExtractors.add(iexplore);
|
||||
|
@ -19,7 +19,6 @@ environment:
|
||||
LIBVHDI_HOME: "C:\\libvhdi_64bit"
|
||||
LIBVMDK_HOME: "C:\\libvmdk_64bit\\libvmdk"
|
||||
LIBEWF_HOME: "C:\\libewf_64bit"
|
||||
POSTGRESQL_HOME_64: "C:\\Program Files\\PostgreSQL\\9.5"
|
||||
JDK_HOME: C:\Program Files\Java\jdk1.8.0
|
||||
PYTHON: "C:\\Python36-x64"
|
||||
|
||||
@ -41,7 +40,7 @@ build_script:
|
||||
- python win32\updateAndBuildAll.py -m
|
||||
- ps: pushd bindings/java
|
||||
- ps: ant -version
|
||||
- cmd: ant dist-PostgreSQL
|
||||
- cmd: ant dist
|
||||
- ps: popd
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- cmd: ant -q build
|
||||
|
BIN
thirdparty/markmckinnon/Export_Srudb_Linux
vendored
Normal file
BIN
thirdparty/markmckinnon/Export_Srudb_Linux
vendored
Normal file
Binary file not shown.
BIN
thirdparty/markmckinnon/Export_srudb_macos
vendored
Normal file
BIN
thirdparty/markmckinnon/Export_srudb_macos
vendored
Normal file
Binary file not shown.
202
thirdparty/markmckinnon/LICENSE-2.0.txt
vendored
Normal file
202
thirdparty/markmckinnon/LICENSE-2.0.txt
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
BIN
thirdparty/markmckinnon/export_srudb_32.exe
vendored
Normal file
BIN
thirdparty/markmckinnon/export_srudb_32.exe
vendored
Normal file
Binary file not shown.
BIN
thirdparty/markmckinnon/export_srudb_64.exe
vendored
Normal file
BIN
thirdparty/markmckinnon/export_srudb_64.exe
vendored
Normal file
Binary file not shown.
@ -4,7 +4,7 @@ set -e
|
||||
echo "Building TSK..."
|
||||
cd sleuthkit/sleuthkit
|
||||
./bootstrap && ./configure --prefix=/usr && make
|
||||
pushd bindings/java && ant -q dist-PostgreSQL && popd
|
||||
pushd bindings/java && ant -q dist && popd
|
||||
|
||||
echo "Building Autopsy..." && echo -en 'travis_fold:start:script.build\\r'
|
||||
cd $TRAVIS_BUILD_DIR/
|
||||
|
@ -57,13 +57,13 @@ fi
|
||||
|
||||
ext_jar_filepath=$PWD/autopsy/modules/ext/sleuthkit-$TSK_VERSION.jar;
|
||||
echo -n "Copying sleuthkit-$TSK_VERSION.jar into the Autopsy directory..."
|
||||
rm -f $ext_jar_filepath;
|
||||
rm -f "$ext_jar_filepath";
|
||||
if [ "$?" -gt 0 ]; then #checking if remove operation failed
|
||||
echo "ERROR: Deleting $ext_jar_filepath failed."
|
||||
echo "Please check your permissions."
|
||||
exit 1
|
||||
else
|
||||
cp $sleuthkit_jar_filepath $ext_jar_filepath
|
||||
cp $sleuthkit_jar_filepath "$ext_jar_filepath"
|
||||
if [ "$?" -ne 0 ]; then # checking copy operation was successful
|
||||
echo "ERROR: Copying $sleuthkit_jar_filepath to $ext_jar_filepath failed."
|
||||
echo "Please check your permissions."
|
||||
|
Loading…
x
Reference in New Issue
Block a user