mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
6225 resolve merge conflicts
This commit is contained in:
commit
c8eef33009
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
||||
OpenIDE-Module-Implementation-Version: 30
|
||||
OpenIDE-Module-Implementation-Version: 31
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
AutoUpdate-Show-In-Client: true
|
||||
AutoUpdate-Essential-Module: true
|
||||
|
@ -126,5 +126,5 @@ nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
spec.version.base=10.18
|
||||
spec.version.base=10.19
|
||||
|
||||
|
@ -251,7 +251,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.3</specification-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -50,7 +50,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction")
|
||||
@ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false)
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Toolbars/Case", position = 106)})
|
||||
@ActionReference(path = "Toolbars/Case", position = 107)})
|
||||
public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -464,7 +464,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
||||
// correlate on blackboard artifact attributes if they exist and supported
|
||||
BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
|
||||
if (bbArtifact != null && CentralRepository.isEnabled()) {
|
||||
ret.addAll(CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact));
|
||||
ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact));
|
||||
}
|
||||
|
||||
// we can correlate based on the MD5 if it is enabled
|
||||
|
130
Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java
Normal file → Executable file
130
Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java
Normal file → Executable file
@ -19,7 +19,9 @@
|
||||
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -32,6 +34,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.CommunicationsUtils;
|
||||
import org.sleuthkit.datamodel.HashUtility;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -59,25 +62,60 @@ public class CorrelationAttributeUtil {
|
||||
return Bundle.CorrelationAttributeUtil_emailaddresses_text();
|
||||
}
|
||||
|
||||
// Defines which artifact types act as the sources for CR data.
|
||||
// Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS
|
||||
// TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the
|
||||
// interesting artifact hit).
|
||||
|
||||
// IMPORTANT: This set should be updated for new artifacts types that need to
|
||||
// be inserted into the CR.
|
||||
private static final Set<Integer> SOURCE_TYPES_FOR_CR_INSERT = new HashSet<Integer>() {{
|
||||
add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID());
|
||||
}};
|
||||
|
||||
/**
|
||||
* Makes zero to many correlation attribute instances from the attributes of
|
||||
* an artifact.
|
||||
*
|
||||
* IMPORTANT: The correlation attribute instances are NOT added to the
|
||||
* central repository by this method.
|
||||
* artifacts that have correlatable data. The intention of this method is to
|
||||
* use the results to save to the CR, not to correlate with them. If you
|
||||
* want to correlate, please use makeCorrAttrsForCorrelation. An artifact that can
|
||||
* have correlatable data != An artifact that should be the source of data
|
||||
* in the CR, so results may be un-necessarily incomplete.
|
||||
*
|
||||
* @param artifact An artifact.
|
||||
*
|
||||
* @return A list, possibly empty, of correlation attribute instances for
|
||||
* the artifact.
|
||||
*/
|
||||
public static List<CorrelationAttributeInstance> makeCorrAttrsFromArtifact(BlackboardArtifact artifact) {
|
||||
return makeCorrAttrsFromArtifact(artifact, true );
|
||||
public static List<CorrelationAttributeInstance> makeCorrAttrsToSave(BlackboardArtifact artifact) {
|
||||
if(SOURCE_TYPES_FOR_CR_INSERT.contains(artifact.getArtifactTypeID())) {
|
||||
// Restrict the correlation attributes to use for saving.
|
||||
// The artifacts which are suitable for saving are a subset of the
|
||||
// artifacts that are suitable for correlating.
|
||||
return makeCorrAttrsForCorrelation(artifact);
|
||||
}
|
||||
// Return an empty collection.
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes zero to many correlation attribute instances from the attributes of
|
||||
* an artifact.
|
||||
* artifacts that have correlatable data. The intention of this method is to
|
||||
* use the results to correlate with, not to save. If you
|
||||
* want to save, please use makeCorrAttrsToSave. An artifact that can
|
||||
* have correlatable data != An artifact that should be the source of data
|
||||
* in the CR, so results may be too lenient.
|
||||
*
|
||||
* IMPORTANT: The correlation attribute instances are NOT added to the
|
||||
* central repository by this method.
|
||||
@ -91,26 +129,22 @@ public class CorrelationAttributeUtil {
|
||||
* checking is easy to forget, while catching exceptions is enforced.
|
||||
*
|
||||
* @param artifact An artifact.
|
||||
* @param resolveSourceArtifact A flag to indicate whether to resolve the
|
||||
* source artifact, if the given artifact is
|
||||
* of type TSK_INTERESTING_ARTIFACT_HIT.
|
||||
*
|
||||
* @return A list, possibly empty, of correlation attribute instances for
|
||||
* the artifact.
|
||||
*/
|
||||
public static List<CorrelationAttributeInstance> makeCorrAttrsFromArtifact(BlackboardArtifact artifact, boolean resolveSourceArtifact) {
|
||||
public static List<CorrelationAttributeInstance> makeCorrAttrsForCorrelation(BlackboardArtifact artifact) {
|
||||
List<CorrelationAttributeInstance> correlationAttrs = new ArrayList<>();
|
||||
|
||||
// If the artifact is of type TSK_INTERESTING_ARTIFACT_HIT, and the caller
|
||||
// has not indicated to resolve the source artifact, then return an empty list.
|
||||
if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) && (resolveSourceArtifact == false) ) {
|
||||
return correlationAttrs;
|
||||
}
|
||||
try {
|
||||
BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact);
|
||||
if (sourceArtifact != null) {
|
||||
int artifactTypeID = sourceArtifact.getArtifactTypeID();
|
||||
if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()
|
||||
if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
||||
BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
|
||||
if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) {
|
||||
makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID);
|
||||
}
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
|
||||
@ -143,6 +177,11 @@ public class CorrelationAttributeUtil {
|
||||
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
|
||||
makeCorrAttrFromAcctArtifact(correlationAttrs, sourceArtifact);
|
||||
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
|
||||
makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, sourceArtifact);
|
||||
}
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
@ -158,6 +197,47 @@ public class CorrelationAttributeUtil {
|
||||
return correlationAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a correlation attribute instance from a phone number attribute of an
|
||||
* artifact.
|
||||
*
|
||||
* @param corrAttrInstances Correlation attributes will be added to this.
|
||||
* @param artifact An artifact with a phone number attribute.
|
||||
*
|
||||
* @throws TskCoreException If there is an error querying the case
|
||||
* database.
|
||||
* @throws CentralRepoException If there is an error querying the central
|
||||
* repository.
|
||||
*/
|
||||
private static void makeCorrAttrsFromCommunicationArtifacts(List<CorrelationAttributeInstance> corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException {
|
||||
CorrelationAttributeInstance corrAttr = null;
|
||||
|
||||
/*
|
||||
* Extract the phone number from the artifact attribute.
|
||||
*/
|
||||
String value = null;
|
||||
if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) {
|
||||
value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString();
|
||||
} else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) {
|
||||
value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString();
|
||||
} else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) {
|
||||
value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize the phone number.
|
||||
*/
|
||||
if (value != null) {
|
||||
if(CommunicationsUtils.isValidPhoneNumber(value)) {
|
||||
value = CommunicationsUtils.normalizePhoneNum(value);
|
||||
corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value);
|
||||
if(corrAttr != null) {
|
||||
corrAttrInstances.add(corrAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated artifact of a "meta-artifact" such as an interesting
|
||||
* artifact hit artifact.
|
||||
@ -192,14 +272,6 @@ public class CorrelationAttributeUtil {
|
||||
* IMPORTANT: The correlation attribute instance is NOT added to the central
|
||||
* repository by this method.
|
||||
*
|
||||
* TODO (Jira-6088): The methods in this low-level, utility class should
|
||||
* throw exceptions instead of logging them. The reason for this is that the
|
||||
* clients of the utility class, not the utility class itself, should be in
|
||||
* charge of error handling policy, per the Autopsy Coding Standard. Note
|
||||
* that clients of several of these methods currently cannot determine
|
||||
* whether receiving a null return value is an error or not, plus null
|
||||
* checking is easy to forget, while catching exceptions is enforced.
|
||||
*
|
||||
* @param corrAttrInstances A list of correlation attribute instances.
|
||||
* @param acctArtifact An account artifact.
|
||||
*
|
||||
@ -211,8 +283,12 @@ public class CorrelationAttributeUtil {
|
||||
BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE));
|
||||
String accountTypeStr = accountTypeAttribute.getValueString();
|
||||
|
||||
// @@TODO Vik-6136: CR currently does not know of custom account types.
|
||||
// Ensure there is a predefined account type for this account.
|
||||
Account.Type predefinedAccountType = Account.Type.PREDEFINED_ACCOUNT_TYPES.stream().filter(type -> type.getTypeName().equalsIgnoreCase(accountTypeStr)).findAny().orElse(null);
|
||||
|
||||
// do not create any correlation attribute instance for a Device account
|
||||
if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) {
|
||||
if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false && predefinedAccountType != null) {
|
||||
|
||||
// Get the corresponding CentralRepoAccountType from the database.
|
||||
CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr);
|
||||
|
@ -296,7 +296,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact);
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact);
|
||||
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) {
|
||||
eamArtifact.setComment(comment);
|
||||
try {
|
||||
@ -369,7 +369,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
if (!hasTagWithConflictingKnownStatus) {
|
||||
//Get the correlation atttributes that correspond to the current BlackboardArtifactTag if their status should be changed
|
||||
//with the initial set of correlation attributes this should be a single correlation attribute
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbTag.getArtifact());
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbTag.getArtifact());
|
||||
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) {
|
||||
CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus());
|
||||
}
|
||||
|
@ -455,11 +455,8 @@ public class IngestEventsListener {
|
||||
List<CorrelationAttributeInstance> eamArtifacts = new ArrayList<>();
|
||||
|
||||
for (BlackboardArtifact bbArtifact : bbArtifacts) {
|
||||
// If the incoming artifact is of type TSK_INTERESTING_ARTIFACT_HIT,
|
||||
// do not resolve to the source artifact, as correlation attributes
|
||||
// for the source artifact would have already been created,
|
||||
// when the event for that source artifact was received.
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact, false);
|
||||
// makeCorrAttrToSave will filter out artifacts which should not be sources of CR data.
|
||||
List<CorrelationAttributeInstance> convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsToSave(bbArtifact);
|
||||
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) {
|
||||
try {
|
||||
// Only do something with this artifact if it's unique within the job
|
||||
|
@ -84,3 +84,6 @@ ManageCasesDialog.closeButton.text=Close
|
||||
ManageCasesDialog.notesLabel.text=Notes:
|
||||
ManageCasesDialog.dataSourcesLabel.text=Data Sources:
|
||||
ManageCasesDialog.caseInfoLabel.text=Case Info:
|
||||
GlobalSettingsPanel.bnTestConfigure.text=Test
|
||||
GlobalSettingsPanel.testStatusLabel.toolTipText=
|
||||
GlobalSettingsPanel.testStatusLabel.text=
|
||||
|
@ -12,15 +12,15 @@ EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository.
|
||||
EamDbSettingsDialog.lbDatabaseType.text=Database Type :
|
||||
EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time.
|
||||
EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database.
|
||||
EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).
|
||||
EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database
|
||||
EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?
|
||||
EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist
|
||||
EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database
|
||||
EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.
|
||||
EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.
|
||||
EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again.
|
||||
EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed
|
||||
EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Central Repository Database exists but is not the right format. Manually delete it or choose a different path (if applicable).
|
||||
EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database
|
||||
EamDbSettingsDialog.okButton.createDbDialog.message=Central Repository Database does not exist, would you like to create it?
|
||||
EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist
|
||||
EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Central Repository Database
|
||||
EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Central Repository Database, please ensure address, port, and login credentials are correct for Postgres server and try again.
|
||||
EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Central Repository Database, please ensure location exists and you have write permissions and try again.
|
||||
EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to Central Repository Database. Please check your settings and try again.
|
||||
EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed
|
||||
EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.
|
||||
EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.
|
||||
EamDbSettingsDialog.textPrompt.dbName=Database Name
|
||||
@ -33,12 +33,16 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings
|
||||
EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database.
|
||||
EamOptionsController.moduleErr=Error processing value changes.
|
||||
EamOptionsController.moduleErr.msg=Value change processing failed.
|
||||
GlobalSettingsPanel.askForCentralRepoDbChoice.customPostgrestChoice.text=Configure PostgreSQL
|
||||
GlobalSettingsPanel.askForCentralRepoDbChoice.disableChoice.text=Disable Central Repository
|
||||
GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database.
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database?
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases.
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository?
|
||||
GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.
|
||||
GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running.
|
||||
GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module.
|
||||
ManageCasesDialog.title.text=Manage Cases
|
||||
@ -147,3 +151,6 @@ ManageCasesDialog.closeButton.text=Close
|
||||
ManageCasesDialog.notesLabel.text=Notes:
|
||||
ManageCasesDialog.dataSourcesLabel.text=Data Sources:
|
||||
ManageCasesDialog.caseInfoLabel.text=Case Info:
|
||||
GlobalSettingsPanel.bnTestConfigure.text=Test
|
||||
GlobalSettingsPanel.testStatusLabel.toolTipText=
|
||||
GlobalSettingsPanel.testStatusLabel.text=
|
||||
|
@ -143,3 +143,5 @@ ManageCasesDialog.closeButton.text=\u9589\u3058\u308b
|
||||
ManageCasesDialog.notesLabel.text=\u5099\u8003:
|
||||
ManageCasesDialog.dataSourcesLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9:
|
||||
ManageCasesDialog.caseInfoLabel.text=\u30b1\u30fc\u30b9\u60c5\u5831:
|
||||
GlobalSettingsPanel.bnTestConfigure.text=\u69cb\u6210
|
||||
GlobalSettingsPanel.testStatusLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5b9f\u884c\u4e2d\u306f\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u8a2d\u5b9a\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093!
|
||||
|
@ -87,7 +87,6 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
private final Collection<JTextField> textBoxes;
|
||||
private final TextBoxChangedListener textBoxChangedListener;
|
||||
private final CentralRepoDbManager manager = new CentralRepoDbManager();
|
||||
private final boolean isMultiUserSelectable = CentralRepoDbManager.isPostgresMultiuserAllowed();
|
||||
private final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer();
|
||||
|
||||
public EamDbSettingsDialog() {
|
||||
@ -95,7 +94,7 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
}
|
||||
|
||||
private boolean isDbChoiceSelectable(CentralRepoDbChoice item) {
|
||||
return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || isMultiUserSelectable);
|
||||
return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || manager.isPostgresMultiuserAllowed());
|
||||
}
|
||||
|
||||
|
||||
@ -159,15 +158,15 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
* @param dialog If non-null value, validates settings and updates 'okay' button enabled state.
|
||||
* @return Whether or not the ultimate status after prompts is okay to continue.
|
||||
*/
|
||||
@NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database",
|
||||
"EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).",
|
||||
"EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist",
|
||||
"EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?",
|
||||
"EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed",
|
||||
"EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again.",
|
||||
"EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.",
|
||||
"EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.",
|
||||
"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database"})
|
||||
@NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database",
|
||||
"EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Central Repository Database exists but is not the right format. Manually delete it or choose a different path (if applicable).",
|
||||
"EamDbSettingsDialog.okButton.createDbDialog.title=Central Repository Database Does Not Exist",
|
||||
"EamDbSettingsDialog.okButton.createDbDialog.message=Central Repository Database does not exist, would you like to create it?",
|
||||
"EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Central Repository Database Connection Failed",
|
||||
"EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to Central Repository Database. Please check your settings and try again.",
|
||||
"EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Central Repository Database, please ensure location exists and you have write permissions and try again.",
|
||||
"EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Central Repository Database, please ensure address, port, and login credentials are correct for Postgres server and try again.",
|
||||
"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Central Repository Database"})
|
||||
private static boolean promptTestStatusWarnings(CentralRepoDbManager manager, EamDbSettingsDialog dialog) {
|
||||
if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) {
|
||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
||||
@ -181,32 +180,44 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(),
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
} else if (manager.getStatus() == DatabaseTestResult.DB_DOES_NOT_EXIST) {
|
||||
//database doesn't exist. do you want to create?
|
||||
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(),
|
||||
Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(),
|
||||
Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(),
|
||||
JOptionPane.YES_NO_OPTION)) {
|
||||
onUserPromptCreateDb(manager, dialog);
|
||||
}
|
||||
promptCreateDatabase(manager, dialog);
|
||||
}
|
||||
|
||||
return (manager.getStatus() == DatabaseTestResult.TESTED_OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When a new database needs to be created on user selecting cr, this code will be ran when user selects create cr.
|
||||
* @param manager The manager handling the database creation.
|
||||
* @param dialog The dialog that prompted database creation.
|
||||
* This method prompts the user whether or not they would like to create a database in the instance that
|
||||
* it doesn't exist.
|
||||
* @param manager The manager to use when setting up the database.
|
||||
* @param dialog If non-null value, validates settings and updates 'okay'
|
||||
* button enabled state.
|
||||
*
|
||||
* @return Whether or not the ultimate status after prompts is okay.
|
||||
*/
|
||||
private static void onUserPromptCreateDb(CentralRepoDbManager manager, EamDbSettingsDialog dialog) {
|
||||
public static boolean promptCreateDatabase(CentralRepoDbManager manager, EamDbSettingsDialog dialog) {
|
||||
//database doesn't exist. do you want to create?
|
||||
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(),
|
||||
Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(),
|
||||
Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(),
|
||||
JOptionPane.YES_NO_OPTION)) {
|
||||
try {
|
||||
manager.createDb();
|
||||
|
||||
} catch (CentralRepoException e) {
|
||||
onPromptStatusError(manager);
|
||||
return false;
|
||||
}
|
||||
if (dialog != null)
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.valid();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return manager.testStatus() == DatabaseTestResult.TESTED_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -604,7 +615,7 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
"EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.",
|
||||
"EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."})
|
||||
private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
|
||||
testStatusAndCreate(this, manager, this);
|
||||
if (testStatusAndCreate(this, manager, this))
|
||||
dispose();
|
||||
}//GEN-LAST:event_bnOkActionPerformed
|
||||
|
||||
@ -659,6 +670,7 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns if changes to the central repository configuration were
|
||||
* successfully applied.
|
||||
@ -887,7 +899,6 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
manager.clearStatus();
|
||||
updateFullDbPath();
|
||||
valid();
|
||||
@ -895,7 +906,6 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
manager.clearStatus();
|
||||
updateFullDbPath();
|
||||
valid();
|
||||
@ -903,7 +913,6 @@ public class EamDbSettingsDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
manager.clearStatus();
|
||||
updateFullDbPath();
|
||||
valid();
|
||||
|
@ -61,7 +61,7 @@
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="pnDatabaseConfiguration" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="pnCorrelationProperties" alignment="0" pref="1010" max="32767" attributes="0"/>
|
||||
<Component id="pnCorrelationProperties" alignment="0" pref="1016" max="32767" attributes="0"/>
|
||||
<Component id="organizationPanel" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="casesPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
@ -137,10 +137,6 @@
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="lbDbPlatformTypeLabel" max="32767" attributes="0"/>
|
||||
@ -149,12 +145,23 @@
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="lbDbNameValue" alignment="0" pref="936" max="32767" attributes="0"/>
|
||||
<Component id="lbDbNameValue" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="lbDbPlatformValue" max="32767" attributes="0"/>
|
||||
<Component id="lbDbLocationValue" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lbDbLocationValue" pref="255" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="681" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="bnTestConfigure" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="testStatusLabel" min="-2" pref="675" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -177,7 +184,13 @@
|
||||
<Component id="lbDbLocationValue" min="-2" pref="14" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="testStatusLabel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="bnDbConfigure" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="bnTestConfigure" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -221,6 +234,40 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lbDbLocationValue">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="bnTestConfigure">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnTestConfigure.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestConfigureActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="testStatusLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="false" component="testStatusLabel" property="font" relativeSize="false" size="11"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="0" green="0" red="ff" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.testStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.testStatusLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[387, 16]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[387, 16]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pnCorrelationProperties">
|
||||
@ -256,7 +303,7 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="correlationPropertiesScrollPane" pref="28" max="32767" attributes="0"/>
|
||||
<Component id="correlationPropertiesScrollPane" pref="24" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.optionspanel;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.EventQueue;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
@ -43,7 +42,13 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings;
|
||||
import java.awt.Component;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Main settings panel for the Central Repository
|
||||
@ -54,18 +59,27 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
|
||||
|
||||
// this allows property change events to be fired at a static level but listened to by instances
|
||||
private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(GlobalSettingsPanel.class);
|
||||
|
||||
// tracks the last known instance property change listener so that only one GlobalSettingsPanel is listening for events
|
||||
private static PropertyChangeListener lastRegistered = null;
|
||||
|
||||
private final IngestJobEventPropertyChangeListener ingestJobEventListener;
|
||||
|
||||
private final ImageIcon goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false));
|
||||
private final ImageIcon badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false));
|
||||
|
||||
|
||||
/**
|
||||
* Creates new form EamOptionsPanel
|
||||
*/
|
||||
public GlobalSettingsPanel() {
|
||||
ingestJobEventListener = new IngestJobEventPropertyChangeListener();
|
||||
|
||||
// listen for change events in currently saved choice
|
||||
CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen()));
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
setupSettingsChangeListeners();
|
||||
addIngestJobEventsListener();
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
//disable when case is open, enable when case is closed
|
||||
@ -73,6 +87,29 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets up this instance's listener for the GlobalSettingsPanel's changes.
|
||||
*/
|
||||
private void setupSettingsChangeListeners() {
|
||||
// listen for change events in currently saved choice
|
||||
if (lastRegistered != null) {
|
||||
CentralRepoDbManager.removePropertyChangeListener(lastRegistered);
|
||||
GlobalSettingsPanel.propertyChangeSupport.removePropertyChangeListener(lastRegistered);
|
||||
}
|
||||
|
||||
lastRegistered = this::onSettingsChange;
|
||||
CentralRepoDbManager.addPropertyChangeListener(lastRegistered);
|
||||
GlobalSettingsPanel.propertyChangeSupport.addPropertyChangeListener(lastRegistered);
|
||||
}
|
||||
|
||||
|
||||
private void onSettingsChange(PropertyChangeEvent evt) {
|
||||
ingestStateUpdated(Case.isCaseOpen());
|
||||
clearStatus();
|
||||
}
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
setName(NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title"));
|
||||
}
|
||||
@ -121,24 +158,23 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) {
|
||||
boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository();
|
||||
boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER;
|
||||
boolean crDisabledDueToFailure = CentralRepoDbManager.isDisabledDueToFailure();
|
||||
|
||||
if (!muPreviouslySelected && muCurrentlySelected) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent,
|
||||
"<html><body>"
|
||||
+ "<div style='width: 400px;'>"
|
||||
+ "<p>" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "</p>"
|
||||
+ "<p style='margin-top: 10px'>" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "</p>"
|
||||
+ "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description() + "</p>"
|
||||
+ "<p style='margin-top: 10px'>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description2() + "</p>"
|
||||
+ "</div>"
|
||||
+ "</body></html>",
|
||||
NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"),
|
||||
Bundle.GlobalSettingsPanel_onMultiUserChange_enable_title(),
|
||||
JOptionPane.YES_NO_OPTION)) {
|
||||
|
||||
// setup database for CR
|
||||
CentralRepoDbUtil.setUseCentralRepo(true);
|
||||
CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER);
|
||||
handleDbChange(parent);
|
||||
checkStatusAndCreateDb(parent);
|
||||
}
|
||||
});
|
||||
} // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected
|
||||
@ -148,13 +184,24 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
});
|
||||
} // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected &&
|
||||
// central repo either enabled or was disabled due to error
|
||||
else if (muPreviouslySelected && muCurrentlySelected && crMultiUser && (crEnabled || crDisabledDueToFailure)) {
|
||||
// test databse for CR change
|
||||
CentralRepoDbUtil.setUseCentralRepo(true);
|
||||
handleDbChange(parent);
|
||||
else if (muPreviouslySelected && muCurrentlySelected && crEnabled && crMultiUser) {
|
||||
GlobalSettingsPanel.propertyChangeSupport.firePropertyChange("multiuserSettingsChanged", null, null);
|
||||
checkStatusAndCreateDb(parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks the status of current connectivity for CR and reports any issues. Will also prompt user to create
|
||||
* database if cr database is absent.
|
||||
* @param parent the parent component to which the dialogs will be associated.
|
||||
*/
|
||||
private static void checkStatusAndCreateDb(Component parent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a user must select a new database other than
|
||||
* using database from multi user settings.
|
||||
@ -165,28 +212,27 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
@NbBundle.Messages({
|
||||
"GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary",
|
||||
"GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.",
|
||||
"GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database."
|
||||
"GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database.",
|
||||
"GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite",
|
||||
"GlobalSettingsPanel.askForCentralRepoDbChoice.customPostgrestChoice.text=Configure PostgreSQL",
|
||||
"GlobalSettingsPanel.askForCentralRepoDbChoice.disableChoice.text=Disable Central Repository"
|
||||
})
|
||||
private static void askForCentralRepoDbChoice(Component parent) {
|
||||
// disable central repository until user makes choice
|
||||
CentralRepoDbUtil.setUseCentralRepo(false);
|
||||
CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED, false);
|
||||
|
||||
Object[] options = {
|
||||
"Use SQLite",
|
||||
"Configure PostgreSQL",
|
||||
"Disable Central Repository"
|
||||
Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_sqliteChoice_text(),
|
||||
Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_customPostgrestChoice_text(),
|
||||
Bundle.GlobalSettingsPanel_askForCentralRepoDbChoice_disableChoice_text()
|
||||
};
|
||||
|
||||
int result = JOptionPane.showOptionDialog(
|
||||
parent,
|
||||
"<html><body>"
|
||||
+ "<div style='width: 400px;'>"
|
||||
+ "<p>" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "</p>"
|
||||
+ "<p style='margin-top: 10px'>" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "</p>"
|
||||
+ "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_description() + "</p>"
|
||||
+ "<p style='margin-top: 10px'>" + Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_description2() + "</p>"
|
||||
+ "</div>"
|
||||
+ "</body></html>",
|
||||
NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"),
|
||||
Bundle.GlobalSettingsPanel_onMultiUserChange_disabledMu_title(),
|
||||
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
null,
|
||||
@ -201,12 +247,54 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleDbChange(Component parent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (!EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager())) {
|
||||
CentralRepoDbManager.disableDueToFailure();
|
||||
@NbBundle.Messages({
|
||||
"GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.",
|
||||
})
|
||||
private boolean testCurrentConfiguration() {
|
||||
if (CentralRepoDbManager.getSavedDbChoice() == null ||
|
||||
CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.DISABLED ||
|
||||
!CentralRepoDbUtil.allowUseOfCentralRepository())
|
||||
return false;
|
||||
|
||||
CentralRepoDbManager manager = new CentralRepoDbManager();
|
||||
DatabaseTestResult testResult = manager.testStatus();
|
||||
|
||||
// if database doesn't exist, prompt user to create database
|
||||
if (testResult == DatabaseTestResult.DB_DOES_NOT_EXIST) {
|
||||
boolean success = EamDbSettingsDialog.promptCreateDatabase(manager, null);
|
||||
if (success)
|
||||
testResult = DatabaseTestResult.TESTED_OK;
|
||||
}
|
||||
|
||||
// display to the user the status
|
||||
switch (testResult) {
|
||||
case TESTED_OK: return showStatusOkay();
|
||||
case DB_DOES_NOT_EXIST: return showStatusFail(Bundle.GlobalSettingsPanel_testCurrentConfiguration_dbDoesNotExist_message());
|
||||
case SCHEMA_INVALID: return showStatusFail(Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message());
|
||||
case CONNECTION_FAILED:
|
||||
default:
|
||||
return showStatusFail(Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showStatusOkay() {
|
||||
return setStatus(goodIcon, " ");
|
||||
}
|
||||
|
||||
private boolean showStatusFail(String message) {
|
||||
return setStatus(badIcon, message);
|
||||
}
|
||||
|
||||
private void clearStatus() {
|
||||
setStatus(null, " ");
|
||||
}
|
||||
|
||||
private boolean setStatus(ImageIcon icon, String text) {
|
||||
synchronized (testStatusLabel) {
|
||||
testStatusLabel.setIcon(icon);
|
||||
testStatusLabel.setText(text);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,6 +318,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
lbDbPlatformValue = new javax.swing.JLabel();
|
||||
lbDbNameValue = new javax.swing.JLabel();
|
||||
lbDbLocationValue = new javax.swing.JLabel();
|
||||
bnTestConfigure = new javax.swing.JButton();
|
||||
testStatusLabel = new javax.swing.JLabel();
|
||||
pnCorrelationProperties = new javax.swing.JPanel();
|
||||
bnManageTypes = new javax.swing.JButton();
|
||||
correlationPropertiesScrollPane = new javax.swing.JScrollPane();
|
||||
@ -278,6 +368,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(bnTestConfigure, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnTestConfigure.text")); // NOI18N
|
||||
bnTestConfigure.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
bnTestConfigureActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
testStatusLabel.setFont(testStatusLabel.getFont().deriveFont(testStatusLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||
testStatusLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||
org.openide.awt.Mnemonics.setLocalizedText(testStatusLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.text")); // NOI18N
|
||||
testStatusLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.testStatusLabel.toolTipText")); // NOI18N
|
||||
testStatusLabel.setMaximumSize(new java.awt.Dimension(387, 16));
|
||||
testStatusLabel.setPreferredSize(new java.awt.Dimension(387, 16));
|
||||
|
||||
javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration);
|
||||
pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout);
|
||||
pnDatabaseConfigurationLayout.setHorizontalGroup(
|
||||
@ -285,9 +389,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
|
||||
.addComponent(bnDbConfigure)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
|
||||
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
@ -295,9 +396,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
.addComponent(lbDbLocationLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 936, Short.MAX_VALUE)
|
||||
.addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnDatabaseConfigurationLayout.createSequentialGroup()
|
||||
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.DEFAULT_SIZE, 255, Short.MAX_VALUE)
|
||||
.addGap(681, 681, 681))))
|
||||
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
|
||||
.addComponent(bnDbConfigure)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(bnTestConfigure)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(testStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 675, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
);
|
||||
pnDatabaseConfigurationLayout.setVerticalGroup(
|
||||
pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -315,7 +425,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
.addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(testStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(bnDbConfigure)
|
||||
.addComponent(bnTestConfigure)))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
@ -359,7 +473,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
pnCorrelationPropertiesLayout.setVerticalGroup(
|
||||
pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnCorrelationPropertiesLayout.createSequentialGroup()
|
||||
.addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)
|
||||
.addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(bnManageTypes)
|
||||
.addGap(8, 8, 8))
|
||||
@ -472,7 +586,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1010, Short.MAX_VALUE)
|
||||
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1016, Short.MAX_VALUE)
|
||||
.addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
@ -532,7 +646,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
boolean changed = invokeCrChoice(this, null);
|
||||
if (changed) {
|
||||
load(); // reload db settings content and update buttons
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_bnDbConfigureActionPerformed
|
||||
|
||||
@ -549,20 +662,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed
|
||||
//if saved setting is disabled checkbox should be disabled already
|
||||
store();
|
||||
|
||||
// if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled
|
||||
if (cbUseCentralRepo.isSelected()
|
||||
&& !CentralRepoDbManager.isPostgresMultiuserAllowed()
|
||||
&& CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) {
|
||||
|
||||
CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED);
|
||||
}
|
||||
|
||||
load();
|
||||
this.ingestStateUpdated(Case.isCaseOpen());
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_cbUseCentralRepoActionPerformed
|
||||
|
||||
private void bnTestConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConfigureActionPerformed
|
||||
testCurrentConfiguration();
|
||||
}//GEN-LAST:event_bnTestConfigureActionPerformed
|
||||
|
||||
@Override
|
||||
@Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
|
||||
public void load() {
|
||||
@ -692,6 +799,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable the Configure button
|
||||
*
|
||||
@ -702,8 +811,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private void enableDatabaseConfigureButton(Boolean enable) {
|
||||
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
|
||||
ingestRunningWarningLabel.setVisible(ingestRunning);
|
||||
|
||||
pnDatabaseConfiguration.setEnabled(enable && !ingestRunning);
|
||||
bnDbConfigure.setEnabled(enable && !ingestRunning);
|
||||
bnTestConfigure.setEnabled(enable && !ingestRunning);
|
||||
lbDbLocationLabel.setEnabled(enable && !ingestRunning);
|
||||
lbDbLocationValue.setEnabled(enable && !ingestRunning);
|
||||
lbDbNameLabel.setEnabled(enable && !ingestRunning);
|
||||
@ -738,6 +849,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton bnDbConfigure;
|
||||
private javax.swing.JButton bnManageTypes;
|
||||
private javax.swing.JButton bnTestConfigure;
|
||||
private javax.swing.JPanel casesPanel;
|
||||
private javax.swing.JScrollPane casesScrollPane;
|
||||
private javax.swing.JTextArea casesTextArea;
|
||||
@ -762,5 +874,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private javax.swing.JPanel pnDatabaseConfiguration;
|
||||
private javax.swing.JButton showCasesButton;
|
||||
private javax.swing.JTextField tbOops;
|
||||
private javax.swing.JLabel testStatusLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonpropertiessearch;
|
||||
|
||||
import org.sleuthkit.autopsy.guiutils.DataSourceComboBoxModel;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -119,6 +120,13 @@ public final class InterCasePanel extends javax.swing.JPanel {
|
||||
this.correlationTypeFilters = new HashMap<>();
|
||||
try {
|
||||
List<CorrelationAttributeInstance.Type> types = CentralRepository.getInstance().getDefinedCorrelationTypes();
|
||||
Collections.sort(types, new Comparator<CorrelationAttributeInstance.Type>() {
|
||||
//The types should be sorted so that the File type is the first item in the combo box.
|
||||
@Override
|
||||
public int compare(CorrelationAttributeInstance.Type type1, CorrelationAttributeInstance.Type type2) {
|
||||
return Integer.compare(type1.getId(), type2.getId());
|
||||
}
|
||||
});
|
||||
for (CorrelationAttributeInstance.Type type : types) {
|
||||
correlationTypeFilters.put(type.getDisplayName(), type);
|
||||
this.correlationTypeComboBox.addItem(type.getDisplayName());
|
||||
@ -329,8 +337,8 @@ public final class InterCasePanel extends javax.swing.JPanel {
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Get the map of cases which was used to populate the combo box on
|
||||
* this panel.
|
||||
* Get the map of cases which was used to populate the combo box on this
|
||||
* panel.
|
||||
*
|
||||
* @return an unmodifiable copy of the map of cases
|
||||
*/
|
||||
@ -339,8 +347,8 @@ public final class InterCasePanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the datamodel for the combo box which displays the cases in
|
||||
* the central repository
|
||||
* Set the datamodel for the combo box which displays the cases in the
|
||||
* central repository
|
||||
*
|
||||
* @param dataSourceComboBoxModel the DataSourceComboBoxModel to use
|
||||
*/
|
||||
|
@ -247,6 +247,8 @@ public class MessageViewer extends JPanel implements RelationshipsViewer {
|
||||
*/
|
||||
private void showMessagesPane() {
|
||||
switchCard("messages");
|
||||
Outline outline = rootTablePane.getOutlineView().getOutline();
|
||||
outline.clearSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +198,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
startSection(html, "Central Repository Comments");
|
||||
List<CorrelationAttributeInstance> instancesList = new ArrayList<>();
|
||||
if (artifact != null) {
|
||||
instancesList.addAll(CorrelationAttributeUtil.makeCorrAttrsFromArtifact(artifact));
|
||||
instancesList.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(artifact));
|
||||
}
|
||||
try {
|
||||
List<CorrelationAttributeInstance.Type> artifactTypes = CentralRepository.getInstance().getDefinedCorrelationTypes();
|
||||
|
@ -77,9 +77,9 @@ DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails: {0}
|
||||
AboutWindowPanel.actVerboseLogging.text=Activate verbose logging
|
||||
OptionsCategory_Name_Multi_User_Settings=Multi-User
|
||||
OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings
|
||||
MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings
|
||||
MultiUserSettingsPanel.lbSolrSettings.text=Solr Server Settings
|
||||
MultiUserSettingsPanel.cbEnableMultiUser.text=Enable multi-user cases
|
||||
MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings
|
||||
MultiUserSettingsPanel.lbDatabaseSettings.text=Database Server Settings
|
||||
MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values
|
||||
MultiUserSettingsPanel.nonWindowsOs.msg=Multi-user cases are only available on Windows platforms
|
||||
MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number
|
||||
@ -107,7 +107,7 @@ MultiUserSettingsPanel.tbSolrHostname.toolTipText=Hostname or IP Address
|
||||
MultiUserSettingsPanel.tbSolrPort.toolTipText=Port Number
|
||||
MultiUserSettingsPanel.lbTestMessageService.text=
|
||||
MultiUserSettingsPanel.bnTestMessageService.text=Test
|
||||
MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Service Settings
|
||||
MultiUserSettingsPanel.lbMessageServiceSettings.text=ActiveMQ Message Server Settings
|
||||
MultiUserSettingsPanel.tbMsgPort.toolTipText=Port Number
|
||||
MultiUserSettingsPanel.tbMsgPort.text=
|
||||
MultiUserSettingsPanel.tbMsgUsername.toolTipText=User Name (optional)
|
||||
|
@ -97,7 +97,7 @@ class GetSCOTask implements Runnable {
|
||||
logger.log(Level.WARNING, "Unable to get correlation type or value to determine value for O column for artifact", ex);
|
||||
}
|
||||
} else {
|
||||
List<CorrelationAttributeInstance> listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact);
|
||||
List<CorrelationAttributeInstance> listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact);
|
||||
if (listOfPossibleAttributes.size() > 1) {
|
||||
//Don't display anything if there is more than 1 correlation property for an artifact but let the user know
|
||||
description = Bundle.GetSCOTask_occurrences_multipleProperties();
|
||||
|
@ -23,6 +23,10 @@ import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.io.Files;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.Paths;
|
||||
@ -79,6 +83,9 @@ import org.sleuthkit.autopsy.textextractors.TextExtractor;
|
||||
import org.sleuthkit.autopsy.textextractors.TextExtractorFactory;
|
||||
import org.sleuthkit.autopsy.textsummarizer.TextSummarizer;
|
||||
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||
import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
|
||||
import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
|
||||
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
||||
|
||||
/**
|
||||
* Main class to perform the file search.
|
||||
@ -306,7 +313,111 @@ class FileSearch {
|
||||
}
|
||||
image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM,
|
||||
Image.SCALE_SMOOTH);
|
||||
return new TextSummary(getFirstLines(file), image, countOfImages);
|
||||
String summaryText = null;
|
||||
if (file.getMd5Hash() != null) {
|
||||
try {
|
||||
summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to retrieve saved summary. No case is open.", ex);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(summaryText)) {
|
||||
String firstLines = getFirstLines(file);
|
||||
String translatedFirstLines = getTranslatedVersion(firstLines);
|
||||
if (!StringUtils.isBlank(translatedFirstLines)) {
|
||||
summaryText = translatedFirstLines;
|
||||
if (file.getMd5Hash() != null) {
|
||||
try {
|
||||
saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to save translated summary. No case is open.", ex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
summaryText = firstLines;
|
||||
}
|
||||
}
|
||||
return new TextSummary(summaryText, image, countOfImages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an English version of the specified String if it is not English,
|
||||
* translation is enabled, and it can be translated.
|
||||
*
|
||||
* @param documentString The String to provide an English version of.
|
||||
*
|
||||
* @return The English version of the provided String, or null if no
|
||||
* translation occurred.
|
||||
*/
|
||||
private static String getTranslatedVersion(String documentString) {
|
||||
try {
|
||||
TextTranslationService translatorInstance = TextTranslationService.getInstance();
|
||||
if (translatorInstance.hasProvider()) {
|
||||
String translatedResult = translatorInstance.translate(documentString);
|
||||
if (translatedResult.isEmpty() == false) {
|
||||
return translatedResult;
|
||||
}
|
||||
}
|
||||
} catch (NoServiceProviderException | TranslationException ex) {
|
||||
logger.log(Level.INFO, "Error translating string for summary", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and load a saved summary from the case folder for the specified
|
||||
* file.
|
||||
*
|
||||
* @param summarySavePath The full path for the saved summary file.
|
||||
*
|
||||
* @return The summary found given the specified path, null if no summary
|
||||
* was found.
|
||||
*/
|
||||
private static String getSavedSummary(String summarySavePath) {
|
||||
if (summarySavePath == null) {
|
||||
return null;
|
||||
}
|
||||
File savedFile = new File(summarySavePath);
|
||||
if (savedFile.exists()) {
|
||||
try (BufferedReader bReader = new BufferedReader(new FileReader(savedFile))) {
|
||||
// pass the path to the file as a parameter
|
||||
StringBuilder sBuilder = new StringBuilder();
|
||||
String sCurrentLine = bReader.readLine();
|
||||
while (sCurrentLine != null) {
|
||||
sBuilder.append(sCurrentLine).append('\n');
|
||||
sCurrentLine = bReader.readLine();
|
||||
}
|
||||
return sBuilder.toString();
|
||||
} catch (IOException ingored) {
|
||||
//summary file may not exist or may be incomplete in which case return null so a summary can be generated
|
||||
return null; //no saved summary was able to be found
|
||||
}
|
||||
} else {
|
||||
try { //if the file didn't exist make sure the parent directories exist before we move on to creating a summary
|
||||
Files.createParentDirs(savedFile);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Unable to create summaries directory in case folder for file at: " + summarySavePath, ex);
|
||||
}
|
||||
return null; //no saved summary was able to be found
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a summary at the specified location.
|
||||
*
|
||||
* @param summary The text of the summary being saved.
|
||||
* @param summarySavePath The full path for the saved summary file.
|
||||
*/
|
||||
private static void saveSummary(String summary, String summarySavePath) {
|
||||
if (summarySavePath == null) {
|
||||
return; //can't save a summary if we don't have a path
|
||||
}
|
||||
try (FileWriter myWriter = new FileWriter(summarySavePath)) {
|
||||
myWriter.write(summary);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Unable to save summary at: " + summarySavePath, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -310,7 +310,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
void setZoom(int zoom) {
|
||||
zoomChanging = true;
|
||||
mapViewer.setZoom(zoom);
|
||||
zoomSlider.setValue((zoomSlider.getMaximum() + zoomSlider.getMinimum()) - zoom);
|
||||
zoomSlider.setValue(zoom);
|
||||
zoomChanging = false;
|
||||
}
|
||||
|
||||
@ -572,6 +572,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
zoomSlider.setOrientation(javax.swing.JSlider.VERTICAL);
|
||||
zoomSlider.setPaintTicks(true);
|
||||
zoomSlider.setSnapToTicks(true);
|
||||
zoomSlider.setInverted(true);
|
||||
zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100));
|
||||
zoomSlider.setOpaque(false);
|
||||
zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190));
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -25,9 +25,9 @@ import java.util.Map;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList.GeoWaypoint;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints;
|
||||
|
||||
/**
|
||||
* A Route represents a TSK_GPS_ROUTE artifact which has a start and end point
|
||||
@ -43,8 +43,6 @@ public class Route extends GeoPath {
|
||||
// constructor will take care of creating an unmodifiable List
|
||||
private final List<Waypoint.Property> propertiesList;
|
||||
|
||||
private static final TskGeoWaypointsUtil attributeUtil = new TskGeoWaypointsUtil();
|
||||
|
||||
/**
|
||||
* Construct a route for the given artifact.
|
||||
*
|
||||
@ -119,9 +117,13 @@ public class Route extends GeoPath {
|
||||
}
|
||||
|
||||
if (attribute != null) {
|
||||
GeoWaypointList waypoints = attributeUtil.fromAttribute(attribute);
|
||||
|
||||
for(GeoWaypoint waypoint: waypoints) {
|
||||
GeoWaypoints waypoints;
|
||||
try {
|
||||
waypoints = BlackboardJsonAttrUtil.fromAttribute(attribute, GeoWaypoints.class);
|
||||
} catch (InvalidJsonException ex) {
|
||||
throw new GeoLocationDataException(String.format("Unable to parse waypoints in TSK_GEO_WAYPOINTS attribute (artifact object ID =%d)", artifact.getId()), ex);
|
||||
}
|
||||
for (GeoWaypoints.Waypoint waypoint : waypoints) {
|
||||
addToPath(new Waypoint(artifact, label, null, waypoint.getLatitude(), waypoint.getLongitude(), waypoint.getAltitude(), null, attributeMap, this));
|
||||
}
|
||||
} else {
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
@ -26,20 +25,18 @@ import java.util.Map;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints;
|
||||
|
||||
/**
|
||||
* A GPS track with which wraps the TSK_GPS_TRACK artifact.
|
||||
*/
|
||||
public final class Track extends GeoPath{
|
||||
public final class Track extends GeoPath {
|
||||
|
||||
private final Long startTimestamp;
|
||||
private final Long endTimeStamp;
|
||||
|
||||
private static final TskGeoTrackpointsUtil attributeUtil = new TskGeoTrackpointsUtil();
|
||||
|
||||
/**
|
||||
* Construct a new Track for the given artifact.
|
||||
*
|
||||
@ -62,7 +59,7 @@ public final class Track extends GeoPath{
|
||||
private Track(BlackboardArtifact artifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) throws GeoLocationDataException {
|
||||
super(artifact, getTrackName(attributeMap));
|
||||
|
||||
GeoTrackPointList points = getPointsList(attributeMap);
|
||||
GeoTrackPoints points = getPointsList(attributeMap);
|
||||
buildPath(points, artifact);
|
||||
|
||||
startTimestamp = points.getStartTime();
|
||||
@ -72,8 +69,8 @@ public final class Track extends GeoPath{
|
||||
/**
|
||||
* Returns the start time of this track.
|
||||
*
|
||||
* @return Earliest time, or null if none was available.
|
||||
* (seconds from java epoch)
|
||||
* @return Earliest time, or null if none was available. (seconds from java
|
||||
* epoch)
|
||||
*/
|
||||
public Long getStartTime() {
|
||||
return startTimestamp;
|
||||
@ -82,19 +79,19 @@ public final class Track extends GeoPath{
|
||||
/**
|
||||
* Returns the end time of this track.
|
||||
*
|
||||
* @return Earliest timestamp, or null if none was available.
|
||||
* (seconds from java epoch)
|
||||
* @return Earliest timestamp, or null if none was available. (seconds from
|
||||
* java epoch)
|
||||
*/
|
||||
public Long getEndTime() {
|
||||
return endTimeStamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the track from the attributeMap.
|
||||
* Track name is stored in the attribute TSK_NAME
|
||||
* Return the name of the track from the attributeMap. Track name is stored
|
||||
* in the attribute TSK_NAME
|
||||
*
|
||||
* @param attributeMap
|
||||
|
||||
*
|
||||
* @return Track name or empty string if none was available.
|
||||
*/
|
||||
private static String getTrackName(Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) {
|
||||
@ -106,8 +103,7 @@ public final class Track extends GeoPath{
|
||||
/**
|
||||
* Create the list of TrackWaypoints from the GeoTrackPoint list.
|
||||
*
|
||||
* @param points List of GeoTrackPoints
|
||||
*
|
||||
* @param points GeoTrackPoints object.
|
||||
* @param artifact The artifact to which these points belong
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
@ -116,9 +112,8 @@ public final class Track extends GeoPath{
|
||||
"# {0} - track name",
|
||||
"GEOTrack_point_label_header=Trackpoint for track: {0}"
|
||||
})
|
||||
private void buildPath(GeoTrackPointList points, BlackboardArtifact artifact)
|
||||
throws GeoLocationDataException {
|
||||
for(GeoTrackPoint point: points) {
|
||||
private void buildPath(GeoTrackPoints points, BlackboardArtifact artifact) throws GeoLocationDataException {
|
||||
for (GeoTrackPoints.TrackPoint point : points) {
|
||||
addToPath(new TrackWaypoint(artifact, Bundle.GEOTrack_point_label_header(getLabel()), point));
|
||||
}
|
||||
}
|
||||
@ -130,13 +125,18 @@ public final class Track extends GeoPath{
|
||||
* @param attributeMap Map of artifact attributes.
|
||||
*
|
||||
* @return GeoTrackPoint list empty list if the attribute was not found.
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
private GeoTrackPointList getPointsList(Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) {
|
||||
private GeoTrackPoints getPointsList(Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) throws GeoLocationDataException {
|
||||
BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS);
|
||||
if (attribute != null) {
|
||||
return attributeUtil.fromAttribute(attribute);
|
||||
try {
|
||||
return BlackboardJsonAttrUtil.fromAttribute(attribute, GeoTrackPoints.class);
|
||||
} catch (InvalidJsonException ex) {
|
||||
throw new GeoLocationDataException("Unable to parse track points in TSK_GEO_TRACKPOINTS attribute", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ public final class Track extends GeoPath{
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
TrackWaypoint(BlackboardArtifact artifact, String pointLabel, GeoTrackPoint point) throws GeoLocationDataException {
|
||||
TrackWaypoint(BlackboardArtifact artifact, String pointLabel, GeoTrackPoints.TrackPoint point) throws GeoLocationDataException {
|
||||
super(artifact, pointLabel,
|
||||
point.getTimeStamp(),
|
||||
point.getLatitude(),
|
||||
@ -172,8 +172,8 @@ public final class Track extends GeoPath{
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded to return a property list that is generated from
|
||||
* the GeoTrackPoint instead of an artifact.
|
||||
* Overloaded to return a property list that is generated from the
|
||||
* GeoTrackPoint instead of an artifact.
|
||||
*
|
||||
* @return unmodifiable list of Waypoint.Property
|
||||
*/
|
||||
@ -193,7 +193,7 @@ public final class Track extends GeoPath{
|
||||
"Track_distanceTraveled_displayName=Distance traveled",
|
||||
"Track_distanceFromHome_displayName=Distance from home point"
|
||||
})
|
||||
private List<Waypoint.Property> createPropertyList(GeoTrackPoint point) {
|
||||
private List<Waypoint.Property> createPropertyList(GeoTrackPoints.TrackPoint point) {
|
||||
List<Waypoint.Property> list = new ArrayList<>();
|
||||
|
||||
Long timestamp = point.getTimeStamp();
|
||||
|
@ -41,11 +41,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint;
|
||||
import org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.TrackPoint;
|
||||
|
||||
/**
|
||||
* Extract drone position data from DJI Phantom drones.
|
||||
@ -111,7 +111,7 @@ final class DATExtractor extends DroneExtractor {
|
||||
}
|
||||
|
||||
// Process the csv file
|
||||
GeoTrackPointList trackPoints = processCSVFile(context, DATFile, csvFilePath);
|
||||
GeoTrackPoints trackPoints = processCSVFile(context, DATFile, csvFilePath);
|
||||
|
||||
if (trackPoints != null && !trackPoints.isEmpty()) {
|
||||
(new GeoArtifactsHelper(getSleuthkitCase(), getName(), "DatCon", DATFile)).addTrack(DATFile.getName(), trackPoints, null);
|
||||
@ -188,8 +188,8 @@ final class DATExtractor extends DroneExtractor {
|
||||
*
|
||||
* @throws DroneIngestException
|
||||
*/
|
||||
private GeoTrackPointList processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException {
|
||||
GeoTrackPointList trackPoints = new GeoTrackPointList();
|
||||
private GeoTrackPoints processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException {
|
||||
GeoTrackPoints trackPoints = new GeoTrackPoints();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(new File(csvFilePath)))) {
|
||||
// First read in the header line and process
|
||||
String line = reader.readLine();
|
||||
@ -201,7 +201,7 @@ final class DATExtractor extends DroneExtractor {
|
||||
}
|
||||
|
||||
String[] values = line.split(","); //NON-NLS
|
||||
GeoTrackPoint point = createTrackPoint(headerMap, values);
|
||||
TrackPoint point = createTrackPoint(headerMap, values);
|
||||
if (point != null) {
|
||||
trackPoints.addPoint(point);
|
||||
}
|
||||
@ -246,7 +246,7 @@ final class DATExtractor extends DroneExtractor {
|
||||
*
|
||||
* @throws DroneIngestException
|
||||
*/
|
||||
private GeoTrackPoint createTrackPoint(Map<String, Integer> columnLookup, String[] values) throws DroneIngestException {
|
||||
private TrackPoint createTrackPoint(Map<String, Integer> columnLookup, String[] values) throws DroneIngestException {
|
||||
|
||||
Double latitude = getDoubleValue(columnLookup.get(HEADER_LAT), values);
|
||||
Double longitude = getDoubleValue(columnLookup.get(HEADER_LONG), values);
|
||||
@ -256,7 +256,7 @@ final class DATExtractor extends DroneExtractor {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new GeoTrackPoint(latitude,
|
||||
return new TrackPoint(latitude,
|
||||
longitude,
|
||||
getDoubleValue(columnLookup.get(HEADER_ALTITUDE), values),
|
||||
null,
|
||||
|
@ -52,6 +52,7 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.CentralRepoHashS
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.SetEvt;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
@ -94,6 +95,17 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
HashDbManager.getInstance().addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String propName = evt.getPropertyName();
|
||||
if(propName.equals(SetEvt.DB_ADDED.toString()) ||
|
||||
propName.equals(SetEvt.DB_DELETED.toString())) {
|
||||
hashSetTableModel.refreshModel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"HashLookupSettingsPanel.Title=Global Hash Lookup Settings"})
|
||||
|
@ -59,7 +59,7 @@ import org.sleuthkit.autopsy.report.ReportModule;
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 301, separatorAfter = 399)
|
||||
,
|
||||
@ActionReference(path = "Toolbars/Case", position = 107)})
|
||||
@ActionReference(path = "Toolbars/Case", position = 106)})
|
||||
public final class ReportWizardAction extends CallableSystemAction implements Presenter.Toolbar, ActionListener {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ReportWizardAction.class.getName());
|
||||
|
@ -1,8 +1,8 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3
|
||||
OpenIDE-Module-Implementation-Version: 6
|
||||
OpenIDE-Module-Implementation-Version: 7
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.3
|
||||
OpenIDE-Module-Specification-Version: 1.4
|
||||
AutoUpdate-Show-In-Client: true
|
||||
AutoUpdate-Essential-Module: true
|
||||
|
||||
|
@ -135,7 +135,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -144,7 +144,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.3</specification-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -57,6 +57,7 @@ import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
@ -83,6 +84,7 @@ class MultiUserTestTool {
|
||||
"MultiUserTestTool.unableCreatFile=Unable to create a file in case output directory",
|
||||
"MultiUserTestTool.unableAddFileAsDataSource=Unable to add test file as data source to case",
|
||||
"MultiUserTestTool.unableToReadTestFileFromDatabase=Unable to read test file info from case database",
|
||||
"MultiUserTestTool.unableToInitializeFilTypeDetector=Unable to initialize File Type Detector",
|
||||
"MultiUserTestTool.unableToUpdateKWSIndex=Unable to write to Keyword Search index",
|
||||
"MultiUserTestTool.unableToRunIngest=Unable to run ingest on test data source",
|
||||
"MultiUserTestTool.unexpectedError=Unexpected error while performing Multi User test",
|
||||
@ -188,6 +190,16 @@ class MultiUserTestTool {
|
||||
|
||||
AbstractFile file = listOfFiles.get(0);
|
||||
|
||||
// Set MIME type of the test file (required to test indexing)
|
||||
FileTypeDetector fileTypeDetector = null;
|
||||
try {
|
||||
fileTypeDetector = new FileTypeDetector();
|
||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||
return Bundle.MultiUserTestTool_unableToInitializeFilTypeDetector() + ". " + ex.getMessage();
|
||||
}
|
||||
String mimeType = fileTypeDetector.getMIMEType(file);
|
||||
file.setMIMEType(mimeType);
|
||||
|
||||
// write to KWS index
|
||||
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||
try {
|
||||
|
@ -127,7 +127,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -136,7 +136,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.3</specification-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -37,12 +37,10 @@ from org.sleuthkit.datamodel import BlackboardArtifact
|
||||
from org.sleuthkit.datamodel import BlackboardAttribute
|
||||
from org.sleuthkit.datamodel import TskCoreException
|
||||
from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoWaypointsUtil
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList import GeoWaypoint
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil import GeoTrackPointList
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList import GeoTrackPoint
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints import Waypoint
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints import TrackPoint
|
||||
from org.sleuthkit.autopsy.datamodel import ContentUtils
|
||||
from org.sleuthkit.autopsy.ingest import IngestModule
|
||||
from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException
|
||||
@ -166,7 +164,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule):
|
||||
if self.writeDebugMsgs: self.log(Level.INFO, "Processing tracks from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")")
|
||||
for track in gpx.tracks:
|
||||
for segment in track.segments:
|
||||
geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList()
|
||||
geoPointList = GeoTrackPoints()
|
||||
for point in segment.points:
|
||||
|
||||
elevation = 0
|
||||
@ -180,7 +178,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule):
|
||||
except Exception as e:
|
||||
self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e))
|
||||
|
||||
geoPointList.addPoint(GeoTrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp))
|
||||
geoPointList.addPoint(TrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp))
|
||||
|
||||
try:
|
||||
geoArtifactHelper.addTrack("Track", geoPointList, None)
|
||||
@ -213,13 +211,13 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule):
|
||||
if self.writeDebugMsgs: self.log(Level.INFO, "Processing routes from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")")
|
||||
for route in gpx.routes:
|
||||
|
||||
geoWaypointList = TskGeoWaypointsUtil.GeoWaypointList()
|
||||
geoWaypoints = GeoWaypoints()
|
||||
|
||||
for point in route.points:
|
||||
geoWaypointList.addPoint(GeoWaypoint(point.latitude, point.longitude, point.elevation, point.name))
|
||||
geoWaypoints.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name))
|
||||
|
||||
try:
|
||||
geoArtifactHelper.addRoute(None, None, geoWaypointList, None)
|
||||
geoArtifactHelper.addRoute(None, None, geoWaypoints, None)
|
||||
except Blackboard.BlackboardException as e:
|
||||
self.log("Error posting GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage())
|
||||
except TskCoreException as e:
|
||||
|
@ -103,10 +103,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer):
|
||||
calleeId = None
|
||||
|
||||
timeStamp = resultSet.getLong("date") / 1000
|
||||
|
||||
number = resultSet.getString("number")
|
||||
if not general.isValidPhoneNumer(number):
|
||||
number = None
|
||||
|
||||
duration = resultSet.getLong("duration") # duration of call is in seconds
|
||||
name = resultSet.getString("name") # name of person dialed or called. None if unregistered
|
||||
|
@ -45,19 +45,15 @@ def appendAttachmentList(msgBody, attachmentsList):
|
||||
"""
|
||||
Checks if the given string might be a phone number.
|
||||
"""
|
||||
def isValidPhoneNumer(data):
|
||||
try:
|
||||
return CommunicationsUtils.normalizePhoneNum(data) is not None
|
||||
except TskCoreException as ex:
|
||||
return False
|
||||
def isValidPhoneNumber(data):
|
||||
return CommunicationsUtils.isValidPhoneNumber(data)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Checks if the given string is a valid email address.
|
||||
"""
|
||||
def isValidEmailAddress(data):
|
||||
try:
|
||||
return CommunicationsUtils.normalizeEmailAddress(data) is not None
|
||||
except TskCoreException as ex:
|
||||
return False
|
||||
return CommunicationsUtils.isValidEmailAddress(data)
|
||||
|
||||
|
||||
|
@ -43,8 +43,8 @@ from org.sleuthkit.datamodel import Content
|
||||
from org.sleuthkit.datamodel import TskCoreException
|
||||
from org.sleuthkit.datamodel.Blackboard import BlackboardException
|
||||
from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList import GeoWaypoint
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoints
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints import Waypoint
|
||||
|
||||
import traceback
|
||||
import general
|
||||
@ -117,9 +117,9 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer):
|
||||
source_lat = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lat"))
|
||||
source_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lng"))
|
||||
|
||||
waypointlist = GeoWaypointList()
|
||||
waypointlist.addPoint(GeoWaypoint(source_lat, source_lng, None, None))
|
||||
waypointlist.addPoint(GeoWaypoint(dest_lat, dest_lng, None, dest_address))
|
||||
waypointlist = GeoWaypoints()
|
||||
waypointlist.addPoint(Waypoint(source_lat, source_lng, None, None))
|
||||
waypointlist.addPoint(Waypoint(dest_lat, dest_lng, None, dest_address))
|
||||
|
||||
artifactHelper.addRoute(dest_title, time, waypointlist, None)
|
||||
|
||||
|
@ -45,7 +45,8 @@ from org.sleuthkit.datamodel import Content
|
||||
from org.sleuthkit.datamodel import TskCoreException
|
||||
from org.sleuthkit.datamodel.Blackboard import BlackboardException
|
||||
from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints
|
||||
from org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints import TrackPoint
|
||||
|
||||
import traceback
|
||||
import general
|
||||
@ -139,14 +140,14 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer):
|
||||
trackpointsQueryString = "SELECT trkptlat, trkptlon, trkptalt, trkpttime FROM trackpoints WHERE trkptseg = " + segmentId
|
||||
trackpointsResultSet = oruxMapsTrackpointsDb.runQuery(trackpointsQueryString)
|
||||
if trackpointsResultSet is not None:
|
||||
geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList()
|
||||
geoPointList = GeoTrackPoints()
|
||||
while trackpointsResultSet.next():
|
||||
latitude = trackpointsResultSet.getDouble("trkptlat")
|
||||
longitude = trackpointsResultSet.getDouble("trkptlon")
|
||||
altitude = trackpointsResultSet.getDouble("trkptalt")
|
||||
time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch
|
||||
|
||||
geoPointList.addPoint(TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time))
|
||||
geoPointList.addPoint(TrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time))
|
||||
|
||||
try:
|
||||
geoartifact = geoArtifactHelper.addTrack(segmentName, geoPointList, None)
|
||||
|
@ -286,7 +286,7 @@ class TextNowContactsParser(TskContactsParser):
|
||||
|
||||
def get_phone(self):
|
||||
number = self.result_set.getString("number")
|
||||
return (number if general.isValidPhoneNumer(number) else None)
|
||||
return (number if general.isValidPhoneNumber(number) else None)
|
||||
|
||||
def get_email(self):
|
||||
# occasionally the 'number' column may have an email address instead
|
||||
|
@ -435,7 +435,7 @@ class WhatsAppContactsParser(TskContactsParser):
|
||||
|
||||
def get_phone(self):
|
||||
number = self.result_set.getString("number")
|
||||
return (number if general.isValidPhoneNumer(number) else None)
|
||||
return (number if general.isValidPhoneNumber(number) else None)
|
||||
|
||||
def get_email(self):
|
||||
# occasionally the 'number' column may have an email address instead
|
||||
|
@ -119,7 +119,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -128,7 +128,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.3</specification-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
29
NEWS.txt
29
NEWS.txt
@ -1,3 +1,32 @@
|
||||
---------------- VERSION 4.15.0 --------------
|
||||
New UI Features:
|
||||
- Added Document view to File Discovery.
|
||||
- Expanded Context Content Viewer to show if an app accessed a file.
|
||||
- Added translation feature to Message Content Viewer.
|
||||
- Added waypoint type filter to the Geolocation viewer.
|
||||
- Added zoom feature to Indexed Text Content Viewer.
|
||||
|
||||
New Ingest Modules Features:
|
||||
- New GPX ingest module.
|
||||
- New Drone ingest module for DJI drones based on DatCon.
|
||||
- Create artifacts for files opened by Adobe Reader, Windows Media Player, Office Docs (Most Recently Used (MRU) and TrustRecords), 7Zip MRU, WinRAR MRU, Applets, Microsoft Management Console (MMC) via RegRipper.
|
||||
|
||||
New Central Repository Features:
|
||||
- Central Repository stores account IDs that were previously seen.
|
||||
- Central Repository is enabled by default to store past hashes. Feature to flag previously seen files is disabled by default.
|
||||
|
||||
Other New Features:
|
||||
- Multi-user cases can be created via command line
|
||||
|
||||
Bug fixes:
|
||||
- Prevent entire application from crashing when gstreamer crashes on videos.
|
||||
- Improve Geolocation viewer with large data sets.
|
||||
- Fix error with non-sector aligned reads on local disks.
|
||||
- Times from Recycle Bin files are now in timeline.
|
||||
- Validate timeline events and ignore events too far in the future.
|
||||
- Moved some database queries off of UI thread.
|
||||
- Remove hard coded sizes from UI that cause issues with other languages.
|
||||
|
||||
---------------- VERSION 4.14.0 --------------
|
||||
Specialized UIs:
|
||||
- New File Discovery UI that allows you to search and filter for certain types of files.
|
||||
|
@ -60,7 +60,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -69,7 +69,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.3</specification-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -47,7 +47,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy User Documentation"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.14.0
|
||||
PROJECT_NUMBER = 4.15.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@ -1025,7 +1025,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = 4.14.0
|
||||
HTML_OUTPUT = 4.15.0
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 31 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1017 B After Width: | Height: | Size: 9.5 KiB |
@ -8,14 +8,14 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w
|
||||
\section install_activemq_prereq Prerequisites
|
||||
|
||||
You will need:
|
||||
- 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html.
|
||||
- 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild (<a href="https://github.com/ojdkbuild/ojdkbuild/releases/download/java-1.8.0-openjdk-1.8.0.242-1.b08/java-1.8.0-openjdk-1.8.0.242-1.b08.ojdkbuild.windows.x86_64.msi"> Link to installer</a>)
|
||||
- Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0.
|
||||
|
||||
|
||||
\section install_activemq_install Installation
|
||||
|
||||
\subsection install_activemq_install_java JRE Installation
|
||||
Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output like the yellow results below, you have a JRE.
|
||||
Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE.
|
||||
<br><br>
|
||||
\image html wherejava.PNG
|
||||
<br><br>
|
||||
|
@ -13,7 +13,7 @@ Solr's embedded ZooKeeper is also used as a coordination service for Autopsy.
|
||||
We use Bitnami Solr, which packages Solr as a Windows service.
|
||||
|
||||
You will need:
|
||||
- A 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html.
|
||||
- A 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. (<a href="https://github.com/ojdkbuild/ojdkbuild/releases/download/java-1.8.0-openjdk-1.8.0.242-1.b08/java-1.8.0-openjdk-1.8.0.242-1.b08.ojdkbuild.windows.x86_64.msi"> Link to installer</a>)
|
||||
- The Apache Solr 4.10.3-0 installation package. This is no longer available from its original source, but you can find it on our site: https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr.
|
||||
-- NOTE: We tested Solr 6 at one point, but ran into stability problems when loading and unloading cores. For now, you need to use Solr 4.
|
||||
- An installed version of Autopsy so that you can copy files from it. You can install Autopsy on one of the planned client systems. You do not need to install it on the Solr server.
|
||||
@ -24,7 +24,11 @@ You will need:
|
||||
\section install_solr_install Installation
|
||||
|
||||
\subsection install_solr_install_java JRE Installation
|
||||
1. JREs are normally installed under "C:\Program Files\Java\jre(version)", so check there to see if you have one installed already. If not, get the installer as listed in the above Prerequisites section and install it with the default settings.
|
||||
1. Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE.
|
||||
<br><br>
|
||||
\image html wherejava.PNG
|
||||
<br><br>
|
||||
If you need the JRE, install it with the default settings.
|
||||
|
||||
\subsection install_solr_install_solr Solr Installation
|
||||
|
||||
@ -52,7 +56,7 @@ The following steps will configure Solr to run using an account that will have a
|
||||
+ <i>++JvmOptions=-Dbootstrap_confdir="C:\Bitnami\solr-4.10.3-0\apache-solr\solr\configsets\AutopsyConfig\conf"</i>
|
||||
+ <i>++JvmOptions=-DzkRun </i>
|
||||
<br>
|
||||
- Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: <i>–-JavaHome="C:\Program Files\Java\jre1.8.0_111"</i>
|
||||
- Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: <i>–-JavaHome="C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1"</i>
|
||||
<br><br>
|
||||
A portion of an updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.
|
||||
<br><br>
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.14.0
|
||||
PROJECT_NUMBER = 4.15.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears a the top of each page and should give viewer a
|
||||
@ -1066,7 +1066,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = api-docs/4.14.0/
|
||||
HTML_OUTPUT = api-docs/4.15.0/
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
|
@ -5,7 +5,7 @@ Report modules allow Autopsy users to create different report types. Autopsy co
|
||||
|
||||
All custom report modules will be general report modules. General report modules have a single method to generate the report. This method gives the module freedom to find and process any data it so chooses. General modules also have the ability to provide a configuration panel, allowing the user to choose from various displayed settings. The report module may then use the user's selection to generate a more specific report.
|
||||
|
||||
General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It contains basic API to start, stop, and add to the progress bar, as well as update the processing label. The module is also expected to check the progress bar's status occasionally to see if the user has manually canceled the report.
|
||||
General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It defines a basic API to start, stop, and increment the progress bar and to update the processing label. The module is also expected to check the progress bar's status occasionally to see if the user has manually canceled the report.
|
||||
|
||||
\section report_create_module Creating a Report Module
|
||||
To create a report module, start off by creating a new Java or Python (Jython) class and implementing (Java) or inheriting (Jython) from org.sleuthkit.autopsy.report.GeneralReportModule. You'll need to override multiple methods including the following:
|
||||
@ -17,11 +17,11 @@ To create a report module, start off by creating a new Java or Python (Jython) c
|
||||
If your report module requires configuration, you'll need to override:
|
||||
- org.sleuthkit.autopsy.report.GeneralReportModule.getConfigurationPanel()
|
||||
|
||||
For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to aquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses.
|
||||
For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to acquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses.
|
||||
|
||||
When updating the progress panel, it is recommended to update it as infrequently as possible, while still keeping the user informed. If your report processes 100,000 files and you chose to update the UI each time a file is reviewed, the UI would freeze when trying to process all your requests. This would cause problems to not only your reporting module, but to other modules running in parallel. A safer approach would be to update the UI every 1,000 files, or when a certain "category" of the files being processed has changed. For example, the HTML report module increments the progress bar and changes the processing label every time a new Blackboard Artifact Type is being processed.
|
||||
|
||||
Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard. This panel can be used to allow the user custom controls over the report. To make this panel, use NetBeans to make a new JPanel class and use its layout interface to put the UI widgets in the places that you want them. Then, your getConfigurationPanel() method should create an instance of that class and return it.
|
||||
Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard. This panel can be used to allow the user to customize the report. To make this panel, use NetBeans to make a new JPanel class and use its layout interface to put the UI widgets in the places that you want them. Then, your getConfigurationPanel() method should create an instance of that class and return it.
|
||||
|
||||
|
||||
Typically a general report module should interact with both the Blackboard API in the org.sleuthkit.datamodel.SleuthkitCase class, in addition to an API (possibly external/thirdparty) to convert Blackboard Artifacts to the desired reporting format.
|
||||
@ -32,7 +32,7 @@ You should call org.sleuthkit.autopsy.casemodule.Case.addReport() with the path
|
||||
|
||||
\subsection report_create_module_indexing Indexing Reports
|
||||
|
||||
After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that it is indexed and can then be found by a user. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code:
|
||||
After you have called org.sleuthkit.autopsy.casemodule.Case.addReport() and created a report, you can pass it to org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService.index() so that the report text is indexed for keyword search. This is most commonly used when an Ingest Module runs a 3rd party tool and the output of that tool is added back into Autopsy as a report. Here is some example code:
|
||||
|
||||
\code{.java}
|
||||
KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||
|
@ -4,10 +4,10 @@ app.title=Autopsy
|
||||
### lowercase version of above
|
||||
app.name=${branding.token}
|
||||
### if left unset, version will default to today's date
|
||||
app.version=4.14.0
|
||||
app.version=4.15.0
|
||||
### build.type must be one of: DEVELOPMENT, RELEASE
|
||||
#build.type=RELEASE
|
||||
build.type=DEVELOPMENT
|
||||
build.type=RELEASE
|
||||
#build.type=DEVELOPMENT
|
||||
|
||||
project.org.netbeans.progress=org-netbeans-api-progress
|
||||
project.org.sleuthkit.autopsy.experimental=Experimental
|
||||
|
@ -36,7 +36,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.18</specification-version>
|
||||
<specification-version>10.19</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
Loading…
x
Reference in New Issue
Block a user