Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 3445-DateFilterDevelop

This commit is contained in:
William Schaefer 2018-02-12 15:55:07 -05:00
commit 1cf6d27778
52 changed files with 4169 additions and 486 deletions

View File

@ -36,10 +36,10 @@ GetTagNameDialog.tagNameExistsTskCore.msg=The {0} tag name already exists in the
OpenLogFolder.error1=Log File Not Found: {0} OpenLogFolder.error1=Log File Not Found: {0}
OpenLogFolder.CouldNotOpenLogFolder=Could not open log folder OpenLogFolder.CouldNotOpenLogFolder=Could not open log folder
CTL_OpenLogFolder=Open Log Folder CTL_OpenLogFolder=Open Log Folder
CTL_OpenOutputFolder=Open Output Folder CTL_OpenOutputFolder=Open Case Folder
OpenOutputFolder.error1=Output Folder Not Found\: {0} OpenOutputFolder.error1=Case Output Folder Not Found\: {0}
OpenOutputFolder.noCaseOpen=No open case, therefore no current output folder available. OpenOutputFolder.noCaseOpen=No open case, therefore no current case output folder available.
OpenOutputFolder.CouldNotOpenOutputFolder=Could not open output folder OpenOutputFolder.CouldNotOpenOutputFolder=Could not open case output folder
ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot
OpenPythonModulesFolderAction.actionName.text=Python Plugins OpenPythonModulesFolderAction.actionName.text=Python Plugins
OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0} OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* The action associated with the Tools/Open Output Folder menu item. It opens a * The action associated with the Tools/Open Case Folder menu item. It opens a
* file explorer window for the root output directory for the currently open * file explorer window for the root output directory for the currently open
* case. If the case is a single-user case, this is the case directory. If the * case. If the case is a single-user case, this is the case directory. If the
* case is a multi-user case, this is a subdirectory of the case directory * case is a multi-user case, this is a subdirectory of the case directory
@ -44,7 +44,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
* This action should only be invoked in the event dispatch thread (EDT). * This action should only be invoked in the event dispatch thread (EDT).
*/ */
@ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = false) @ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = false)
@ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849) @ActionReference(path = "Menu/Case", position = 302)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help") @ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help")
public final class OpenOutputFolderAction extends CallableSystemAction { public final class OpenOutputFolderAction extends CallableSystemAction {
@ -61,7 +61,7 @@ public final class OpenOutputFolderAction extends CallableSystemAction {
try { try {
Desktop.getDesktop().open(outputDir); Desktop.getDesktop().open(outputDir);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Failed to open output folder %s", outputDir), ex); //NON-NLS logger.log(Level.SEVERE, String.format("Failed to open case output folder %s", outputDir), ex); //NON-NLS
NotifyDescriptor descriptor = new NotifyDescriptor.Message( NotifyDescriptor descriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE); NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor); DialogDisplayer.getDefault().notify(descriptor);

View File

@ -29,6 +29,8 @@ import org.netbeans.swing.outline.Outline;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.LinkOption;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
@ -207,28 +209,34 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
List<String> nodeList = CoordinationService.getInstance().getNodeList(CoordinationService.CategoryNode.CASES); List<String> nodeList = CoordinationService.getInstance().getNodeList(CoordinationService.CategoryNode.CASES);
for (String node : nodeList) { for (String node : nodeList) {
Path casePath = Paths.get(node); Path casePath;
File caseFolder = casePath.toFile(); try {
if (caseFolder.exists()) { casePath = Paths.get(node).toRealPath(LinkOption.NOFOLLOW_LINKS);
/*
* Search for '*.aut' files. File caseFolder = casePath.toFile();
*/ if (caseFolder.exists()) {
File[] fileArray = caseFolder.listFiles(); /*
if (fileArray == null) { * Search for '*.aut' files.
continue; */
} File[] fileArray = caseFolder.listFiles();
String autFilePath = null; if (fileArray == null) {
for (File file : fileArray) { continue;
String name = file.getName().toLowerCase(); }
if (autFilePath == null && name.endsWith(".aut")) { String autFilePath = null;
try { for (File file : fileArray) {
caseList.add(new CaseMetadata(Paths.get(file.getAbsolutePath()))); String name = file.getName().toLowerCase();
} catch (CaseMetadata.CaseMetadataException ex) { if (autFilePath == null && name.endsWith(".aut")) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex); try {
caseList.add(new CaseMetadata(Paths.get(file.getAbsolutePath())));
} catch (CaseMetadata.CaseMetadataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
}
break;
} }
break;
} }
} }
} catch (IOException ignore) {
//if a path could not be resolved to a real path do add it to the caseList
} }
} }
return caseList; return caseList;

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -61,6 +61,11 @@ class CaseInformationPanel extends javax.swing.JPanel {
@Override @Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize()); tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
if (tabbedPane.getSelectedComponent() instanceof CasePropertiesPanel) {
editDetailsButton.setVisible(true);
} else {
editDetailsButton.setVisible(false);
}
} }
}); });
} }

View File

@ -489,12 +489,16 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId)); corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
corAttrInstances.forEach((corAttrInstance) -> { corAttrInstances.forEach((corAttrInstance) -> {
CorrelationAttribute newCeArtifact = new CorrelationAttribute( try {
corAttr.getCorrelationType(), CorrelationAttribute newCeArtifact = new CorrelationAttribute(
corAttr.getCorrelationValue() corAttr.getCorrelationType(),
); corAttr.getCorrelationValue()
newCeArtifact.addInstance(corAttrInstance); );
tableModel.addEamArtifact(newCeArtifact); newCeArtifact.addInstance(corAttrInstance);
tableModel.addEamArtifact(newCeArtifact);
} catch (EamDbException ex){
LOGGER.log(Level.SEVERE, "Error creating correlation attribute", ex);
}
}); });
} }

View File

@ -271,6 +271,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void updateCase(CorrelationCase eamCase) throws EamDbException { public void updateCase(CorrelationCase eamCase) throws EamDbException {
if(eamCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -444,6 +448,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
if(correlationCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
Connection conn = connect(); Connection conn = connect();
CorrelationDataSource eamDataSourceResult = null; CorrelationDataSource eamDataSourceResult = null;
@ -513,6 +521,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException { public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact == null) {
throw new EamDbException("CorrelationAttribute is null");
}
if(eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
if(eamArtifact.getCorrelationValue() == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect(); Connection conn = connect();
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances(); List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
@ -531,6 +549,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement = conn.prepareStatement(sql.toString());
for (CorrelationAttributeInstance eamInstance : eamInstances) { for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) { if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("CorrelationAttributeInstance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("CorrelationAttributeInstance has null data source");
}
if(eamInstance.getKnownStatus() == null) {
throw new EamDbException("CorrelationAttributeInstance has null known status");
}
preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID()); preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
@ -567,6 +595,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>(); List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -619,6 +650,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException { public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
if(filePath == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect(); Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>(); List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -641,7 +678,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
try { try {
preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement = conn.prepareStatement(sql.toString());
preparedStatement.setString(1, filePath); preparedStatement.setString(1, filePath.toLowerCase());
resultSet = preparedStatement.executeQuery(); resultSet = preparedStatement.executeQuery();
while (resultSet.next()) { while (resultSet.next()) {
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet); artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
@ -670,6 +707,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
if(value == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect(); Connection conn = connect();
Long instanceCount = 0L; Long instanceCount = 0L;
@ -684,7 +728,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
try { try {
preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement = conn.prepareStatement(sql.toString());
preparedStatement.setString(1, value); preparedStatement.setString(1, value.toLowerCase());
resultSet = preparedStatement.executeQuery(); resultSet = preparedStatement.executeQuery();
resultSet.next(); resultSet.next();
instanceCount = resultSet.getLong(1); instanceCount = resultSet.getLong(1);
@ -701,6 +745,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override @Override
public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException { public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException {
if (corAttr == null) {
throw new EamDbException("Correlation attribute is null");
}
Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue(); Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue(); Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100; Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
@ -719,6 +766,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
Long instanceCount = 0L; Long instanceCount = 0L;
@ -840,6 +891,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override @Override
public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException { public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
synchronized (bulkArtifacts) { synchronized (bulkArtifacts) {
bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact); bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact);
bulkArtifactsCount++; bulkArtifactsCount++;
@ -893,6 +948,17 @@ public abstract class AbstractSqlEamDb implements EamDb {
for (CorrelationAttributeInstance eamInstance : eamInstances) { for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) { if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation attribute instance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation attribute instance has null data source");
}
if(eamInstance.getKnownStatus()== null) {
throw new EamDbException("Correlation attribute instance has null known known status");
}
bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID()); bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
@ -929,12 +995,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException { public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
Connection conn = connect(); if(cases == null) {
throw new EamDbException("cases argument is null");
}
if (cases.isEmpty()) { if (cases.isEmpty()) {
return; return;
} }
Connection conn = connect();
int counter = 0; int counter = 0;
PreparedStatement bulkPs = null; PreparedStatement bulkPs = null;
try { try {
@ -1012,8 +1082,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
Connection conn = connect(); if(eamArtifact == null) {
throw new EamDbException("Correlation attribute is null");
}
if(knownStatus == null) {
throw new EamDbException("Known status is null");
}
if (1 != eamArtifact.getInstances().size()) { if (1 != eamArtifact.getInstances().size()) {
throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS
} }
@ -1021,6 +1095,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances(); List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
CorrelationAttributeInstance eamInstance = eamInstances.get(0); CorrelationAttributeInstance eamInstance = eamInstances.get(0);
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation case is null");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation data source is null");
}
Connection conn = connect();
PreparedStatement preparedUpdate = null; PreparedStatement preparedUpdate = null;
PreparedStatement preparedQuery = null; PreparedStatement preparedQuery = null;
ResultSet resultSet = null; ResultSet resultSet = null;
@ -1103,6 +1186,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>(); List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -1153,6 +1240,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
Long badInstances = 0L; Long badInstances = 0L;
@ -1197,6 +1288,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
Collection<String> caseNames = new LinkedHashSet<>(); Collection<String> caseNames = new LinkedHashSet<>();
@ -1313,7 +1408,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override @Override
public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException { public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException {
EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID); EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
if (refSet == null) { if(refSet == null) {
return false; return false;
} }
@ -1382,6 +1477,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException { public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("null correlation type");
}
// TEMP: Only support file correlation type // TEMP: Only support file correlation type
if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) { if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) {
@ -1424,6 +1522,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public long newOrganization(EamOrganization eamOrg) throws EamDbException { public long newOrganization(EamOrganization eamOrg) throws EamDbException {
if(eamOrg == null) {
throw new EamDbException("EamOrganization is null");
}
Connection conn = connect(); Connection conn = connect();
ResultSet generatedKeys = null; ResultSet generatedKeys = null;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -1529,6 +1631,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException { public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
EamGlobalSet globalSet = getReferenceSetByID(referenceSetID); EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
if(globalSet == null) {
throw new EamDbException("Reference set with ID " + referenceSetID + " not found");
}
return (getOrganizationByID(globalSet.getOrgID())); return (getOrganizationByID(globalSet.getOrgID()));
} }
@ -1542,6 +1647,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException { public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
if(updatedOrganization == null) {
throw new EamDbException("null updatedOrganization");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?"; String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
@ -1566,6 +1675,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
"AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."}) "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
@Override @Override
public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException { public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
if(organizationToDelete == null) {
throw new EamDbException("Organization to delete is null");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement checkIfUsedStatement = null; PreparedStatement checkIfUsedStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
@ -1605,6 +1718,18 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException { public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
if(eamGlobalSet == null){
throw new EamDbException("EamGlobalSet argument is null");
}
if(eamGlobalSet.getFileKnownStatus() == null){
throw new EamDbException("File known status on the EamGlobalSet is null");
}
if(eamGlobalSet.getType() == null){
throw new EamDbException("Type on the EamGlobalSet is null");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement1 = null; PreparedStatement preparedStatement1 = null;
@ -1666,8 +1791,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement1 = conn.prepareStatement(sql1); preparedStatement1 = conn.prepareStatement(sql1);
preparedStatement1.setInt(1, referenceSetID); preparedStatement1.setInt(1, referenceSetID);
resultSet = preparedStatement1.executeQuery(); resultSet = preparedStatement1.executeQuery();
resultSet.next(); if(resultSet.next()) {
return getEamGlobalSetFromResultSet(resultSet); return getEamGlobalSetFromResultSet(resultSet);
} else {
return null;
}
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting reference set by id.", ex); // NON-NLS throw new EamDbException("Error getting reference set by id.", ex); // NON-NLS
@ -1689,6 +1817,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException { public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
if(correlationType == null){
throw new EamDbException("Correlation type is null");
}
List<EamGlobalSet> results = new ArrayList<>(); List<EamGlobalSet> results = new ArrayList<>();
Connection conn = connect(); Connection conn = connect();
@ -1723,6 +1856,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException { public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
if(eamGlobalFileInstance.getKnownStatus() == null){
throw new EamDbException("known status of EamGlobalFileInstance is null");
}
if(correlationType == null){
throw new EamDbException("Correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -1786,6 +1926,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException { public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
if(contentType == null) {
throw new EamDbException("Null correlation type");
}
if(globalInstances == null) {
throw new EamDbException("Null set of EamGlobalFileInstance");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement bulkPs = null; PreparedStatement bulkPs = null;
@ -1799,6 +1946,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType))); bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType)));
for (EamGlobalFileInstance globalInstance : globalInstances) { for (EamGlobalFileInstance globalInstance : globalInstances) {
if(globalInstance.getKnownStatus() == null){
throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status");
}
bulkPs.setInt(1, globalInstance.getGlobalSetID()); bulkPs.setInt(1, globalInstance.getGlobalSetID());
bulkPs.setString(2, globalInstance.getMD5Hash()); bulkPs.setString(2, globalInstance.getMD5Hash());
bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue()); bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
@ -1808,7 +1959,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkPs.executeBatch(); bulkPs.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException ex) { } catch (SQLException | EamDbException ex) {
try { try {
conn.rollback(); conn.rollback();
} catch (SQLException ex2) { } catch (SQLException ex2) {
@ -1833,6 +1984,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException { public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
if(aType == null) {
throw new EamDbException("correlation type is null");
}
Connection conn = connect(); Connection conn = connect();
List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>(); List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>();
@ -1869,6 +2024,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/ */
@Override @Override
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException { public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException {
if (newType == null) {
throw new EamDbException("null correlation type");
}
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -1883,7 +2042,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
} else { } else {
insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)"; insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
} }
querySql = "SELECT id FROM correlation_types WHERE display_name=? AND db_table_name=?"; querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
try { try {
preparedStatement = conn.prepareStatement(insertSql); preparedStatement = conn.prepareStatement(insertSql);
@ -2073,9 +2232,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql); preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1, typeId); preparedStatement.setInt(1, typeId);
resultSet = preparedStatement.executeQuery(); resultSet = preparedStatement.executeQuery();
resultSet.next(); if(resultSet.next()) {
aType = getCorrelationTypeFromResultSet(resultSet); aType = getCorrelationTypeFromResultSet(resultSet);
return aType; return aType;
} else {
throw new EamDbException("Failed to find entry for correlation type ID = " + typeId);
}
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS
@ -2131,8 +2293,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} }
CorrelationDataSource eamDataSource = new CorrelationDataSource( CorrelationDataSource eamDataSource = new CorrelationDataSource(
resultSet.getInt("id"),
resultSet.getInt("case_id"), resultSet.getInt("case_id"),
resultSet.getInt("id"),
resultSet.getString("device_id"), resultSet.getString("device_id"),
resultSet.getString("name") resultSet.getString("name")
); );
@ -2166,13 +2328,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
* *
* @throws SQLException when an expected column name is not in the resultSet * @throws SQLException when an expected column name is not in the resultSet
*/ */
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException { private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
if (null == resultSet) { if (null == resultSet) {
return null; return null;
} }
CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance(
new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")),
new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), new CorrelationDataSource(resultSet.getInt("case_id"), -1, resultSet.getString("device_id"), resultSet.getString("name")),
resultSet.getString("file_path"), resultSet.getString("file_path"),
resultSet.getString("comment"), resultSet.getString("comment"),
TskData.FileKnown.valueOf(resultSet.getByte("known_status")) TskData.FileKnown.valueOf(resultSet.getByte("known_status"))
@ -2216,7 +2378,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
return eamGlobalSet; return eamGlobalSet;
} }
private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException { private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
if (null == resultSet) { if (null == resultSet) {
return null; return null;
} }

View File

@ -28,7 +28,7 @@ import org.openide.util.NbBundle.Messages;
/** /**
* Represents a type and value pair that can be used for correlation. * Represents a type and value pair that can be used for correlation.
* CorrelationAttributeInstances store information about the actual * CorrelationAttributeInstances store information about the actual
* occurences of the attribute. * occurrences of the attribute.
*/ */
public class CorrelationAttribute implements Serializable { public class CorrelationAttribute implements Serializable {
@ -66,7 +66,10 @@ public class CorrelationAttribute implements Serializable {
return DEFAULT_CORRELATION_TYPES; return DEFAULT_CORRELATION_TYPES;
} }
public CorrelationAttribute(Type correlationType, String correlationValue) { public CorrelationAttribute(Type correlationType, String correlationValue) throws EamDbException {
if(correlationValue == null) {
throw new EamDbException ("Correlation value is null");
}
this.ID = ""; this.ID = "";
this.correlationType = correlationType; this.correlationType = correlationType;
// Lower-case all values to normalize and improve correlation hits, going forward make sure this makes sense for all correlation types // Lower-case all values to normalize and improve correlation hits, going forward make sure this makes sense for all correlation types
@ -181,9 +184,12 @@ public class CorrelationAttribute implements Serializable {
* Must start with a lowercase letter and only contain * Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters. * lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported * @param supported Is this Type currently supported
* @param enabled Is this Type currentl enabled. * @param enabled Is this Type currently enabled.
*/ */
public Type(int id, String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException { public Type(int id, String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException {
if(dbTableName == null) {
throw new EamDbException("dbTableName is null");
}
this.id = id; this.id = id;
this.displayName = displayName; this.displayName = displayName;
this.dbTableName = dbTableName; this.dbTableName = dbTableName;
@ -195,7 +201,7 @@ public class CorrelationAttribute implements Serializable {
} }
/** /**
* Constructior for custom types where we do not know the Type ID until * Constructor for custom types where we do not know the Type ID until
* the row has been entered into the correlation_types table * the row has been entered into the correlation_types table
* in the central repository. * in the central repository.
* *
@ -204,7 +210,7 @@ public class CorrelationAttribute implements Serializable {
* Must start with a lowercase letter and only contain * Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters. * lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported * @param supported Is this Type currently supported
* @param enabled Is this Type currentl enabled. * @param enabled Is this Type currently enabled.
*/ */
public Type(String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException { public Type(String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException {
this(-1, displayName, dbTableName, supported, enabled); this(-1, displayName, dbTableName, supported, enabled);

View File

@ -46,7 +46,7 @@ public class CorrelationAttributeInstance implements Serializable {
public CorrelationAttributeInstance( public CorrelationAttributeInstance(
CorrelationCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource CorrelationDataSource eamDataSource
) { ) throws EamDbException {
this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN); this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN);
} }
@ -54,7 +54,7 @@ public class CorrelationAttributeInstance implements Serializable {
CorrelationCase eamCase, CorrelationCase eamCase,
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath String filePath
) { ) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN); this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN);
} }
@ -63,7 +63,7 @@ public class CorrelationAttributeInstance implements Serializable {
CorrelationDataSource eamDataSource, CorrelationDataSource eamDataSource,
String filePath, String filePath,
String comment String comment
) { ) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN); this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN);
} }
@ -73,7 +73,7 @@ public class CorrelationAttributeInstance implements Serializable {
String filePath, String filePath,
String comment, String comment,
TskData.FileKnown knownStatus TskData.FileKnown knownStatus
) { ) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, comment, knownStatus); this(-1, eamCase, eamDataSource, filePath, comment, knownStatus);
} }
@ -84,7 +84,11 @@ public class CorrelationAttributeInstance implements Serializable {
String filePath, String filePath,
String comment, String comment,
TskData.FileKnown knownStatus TskData.FileKnown knownStatus
) { ) throws EamDbException {
if(filePath == null) {
throw new EamDbException("file path is null");
}
this.ID = ID; this.ID = ID;
this.correlationCase = eamCase; this.correlationCase = eamCase;
this.correlationDataSource = eamDataSource; this.correlationDataSource = eamDataSource;

View File

@ -50,6 +50,10 @@ public class CorrelationCase implements Serializable {
* @param caseUUID Globally unique identifier * @param caseUUID Globally unique identifier
* @param displayName * @param displayName
*/ */
public CorrelationCase(String caseUUID, String displayName) {
this(-1, caseUUID, displayName);
}
CorrelationCase(int ID, String caseUUID, String displayName) { CorrelationCase(int ID, String caseUUID, String displayName) {
this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null); this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
} }
@ -156,7 +160,7 @@ public class CorrelationCase implements Serializable {
/** /**
* @return the database ID for the case or -1 if it is unknown (or not in the DB) * @return the database ID for the case or -1 if it is unknown (or not in the DB)
*/ */
int getID() { public int getID() {
// @@@ Should probably have some lazy logic here to lead the ID from the DB if it is -1 // @@@ Should probably have some lazy logic here to lead the ID from the DB if it is -1
return databaseId; return databaseId;
} }

View File

@ -38,6 +38,16 @@ public class CorrelationDataSource implements Serializable {
private final String deviceID; //< Unique to its associated case (not necessarily globally unique) private final String deviceID; //< Unique to its associated case (not necessarily globally unique)
private final String name; private final String name;
/**
*
* @param caseId
* @param deviceId
* @param name
*/
public CorrelationDataSource(int caseId, String deviceId, String name) {
this(caseId, -1, deviceId, name);
}
CorrelationDataSource(int caseId, CorrelationDataSource(int caseId,
int dataSourceId, int dataSourceId,
String deviceId, String deviceId,

View File

@ -135,7 +135,8 @@ public class EamArtifactUtil {
* @return the new EamArtifact, or null if one was not created because * @return the new EamArtifact, or null if one was not created because
* bbArtifact did not contain the needed data * bbArtifact did not contain the needed data
*/ */
private static CorrelationAttribute getCorrelationAttributeFromBlackboardArtifact(CorrelationAttribute.Type correlationType, BlackboardArtifact bbArtifact) { private static CorrelationAttribute getCorrelationAttributeFromBlackboardArtifact(CorrelationAttribute.Type correlationType,
BlackboardArtifact bbArtifact) throws EamDbException {
String value = null; String value = null;
int artifactTypeID = bbArtifact.getArtifactTypeID(); int artifactTypeID = bbArtifact.getArtifactTypeID();

View File

@ -36,7 +36,7 @@ public class EamGlobalFileInstance {
int globalSetID, int globalSetID,
String MD5Hash, String MD5Hash,
TskData.FileKnown knownStatus, TskData.FileKnown knownStatus,
String comment) { String comment) throws EamDbException {
this(-1, globalSetID, MD5Hash, knownStatus, comment); this(-1, globalSetID, MD5Hash, knownStatus, comment);
} }
@ -45,7 +45,13 @@ public class EamGlobalFileInstance {
int globalSetID, int globalSetID,
String MD5Hash, String MD5Hash,
TskData.FileKnown knownStatus, TskData.FileKnown knownStatus,
String comment) { String comment) throws EamDbException {
if(MD5Hash == null){
throw new EamDbException("null MD5 hash");
}
if(knownStatus == null){
throw new EamDbException("null known status");
}
this.instanceID = instanceID; this.instanceID = instanceID;
this.globalSetID = globalSetID; this.globalSetID = globalSetID;
// Normalize hashes by lower casing // Normalize hashes by lower casing
@ -111,7 +117,10 @@ public class EamGlobalFileInstance {
/** /**
* @param MD5Hash the MD5Hash to set * @param MD5Hash the MD5Hash to set
*/ */
public void setMD5Hash(String MD5Hash) { public void setMD5Hash(String MD5Hash) throws EamDbException {
if(MD5Hash == null){
throw new EamDbException("null MD5 hash");
}
// Normalize hashes by lower casing // Normalize hashes by lower casing
this.MD5Hash = MD5Hash.toLowerCase(); this.MD5Hash = MD5Hash.toLowerCase();
} }

View File

@ -22,6 +22,7 @@ import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -165,6 +166,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
connectionPool.setMaxIdle(-1); connectionPool.setMaxIdle(-1);
connectionPool.setMaxWaitMillis(1000); connectionPool.setMaxWaitMillis(1000);
connectionPool.setValidationQuery(dbSettings.getValidationQuery()); connectionPool.setValidationQuery(dbSettings.getValidationQuery());
connectionPool.setConnectionInitSqls(Arrays.asList("PRAGMA foreign_keys = ON"));
} }
/** /**

View File

@ -35,5 +35,11 @@ MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments
MessageContentViewer.viewInNewWindowButton.text=View in New Window MessageContentViewer.viewInNewWindowButton.text=View in New Window
JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file: JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file:
JPEGViewerDummy.jTextField1.text=jTextField1 JPEGViewerDummy.jTextField1.text=jTextField1
SQLiteViewer.jLabel1.text=Table SQLiteViewer.nextPageButton.text=
SQLiteViewer.prevPageButton.text=
SQLiteViewer.numPagesLabel.text=N
SQLiteViewer.jLabel3.text=of
SQLiteViewer.currPageLabel.text=x
SQLiteViewer.jLabel2.text=Page
SQLiteViewer.numEntriesField.text=num Entries SQLiteViewer.numEntriesField.text=num Entries
SQLiteViewer.jLabel1.text=Table

View File

@ -0,0 +1,88 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
public class SQLiteTableRowFactory extends ChildFactory<Integer> {
private final List<Map<String, Object>> rows;
public SQLiteTableRowFactory(List<Map<String, Object>> rows) {
this.rows = rows;
}
@Override
protected boolean createKeys(List<Integer> keys) {
if (rows != null) {
for (int i = 0; i < rows.size(); i++) {
keys.add(i);
}
}
return true;
}
@Override
protected Node createNodeForKey(Integer key) {
if (Objects.isNull(rows) || rows.isEmpty() || key >= rows.size()) {
return null;
}
return new SQLiteTableRowNode(rows.get(key));
}
}
class SQLiteTableRowNode extends AbstractNode {
private final Map<String, Object> row;
SQLiteTableRowNode(Map<String, Object> row) {
super(Children.LEAF);
this.row = row;
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set properties = s.get(Sheet.PROPERTIES);
if (properties == null) {
properties = Sheet.createPropertiesSet();
s.put(properties);
}
for (Map.Entry<String, Object> col : row.entrySet()) {
String colName = col.getKey();
String colVal = col.getValue().toString();
properties.put(new NodeProperty<>(colName, colName, colName, colVal)); // NON-NLS
}
return s;
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
</Form>

View File

@ -0,0 +1,163 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingWorker;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.netbeans.swing.etable.ETableColumn;
import org.netbeans.swing.etable.ETableColumnModel;
import org.netbeans.swing.outline.Outline;
import org.openide.explorer.ExplorerManager;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
class SQLiteTableView extends JPanel implements ExplorerManager.Provider {
private final org.openide.explorer.view.OutlineView outlineView;
private final Outline outline;
private final ExplorerManager explorerManager;
/**
* Creates new form SQLiteTableView
*
*/
SQLiteTableView() {
initComponents();
outlineView = new org.openide.explorer.view.OutlineView();
add(outlineView, BorderLayout.CENTER);
outlineView.setPropertyColumns(); // column headers will be set later
outlineView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
outlineView.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
outline = outlineView.getOutline();
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
outline.setRowSelectionAllowed(false);
outline.setRootVisible(false);
explorerManager = new ExplorerManager();
}
/**
* Sets up the columns in the display table
*
* @param tableRows
*/
void setupTable(List<Map<String, Object>> tableRows) {
if (Objects.isNull(tableRows) || tableRows.isEmpty()) {
outlineView.setPropertyColumns();
} else {
// Set up the column names
Map<String, Object> row = tableRows.get(0);
String[] propStrings = new String[row.size() * 2];
int i = 0;
for (Map.Entry<String, Object> col : row.entrySet()) {
String colName = col.getKey();
propStrings[2 * i] = colName;
propStrings[2 * i + 1] = colName;
i++;
}
outlineView.setPropertyColumns(propStrings);
}
// Hide the 'Nodes' column
TableColumnModel columnModel = outline.getColumnModel();
ETableColumn column = (ETableColumn) columnModel.getColumn(0);
((ETableColumnModel) columnModel).setColumnHidden(column, true);
// Set the Nodes for the ExplorerManager.
// The Swingworker ensures that setColumnWidths() is called after all nodes have been created.
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
explorerManager.setRootContext(new AbstractNode(Children.create(new SQLiteTableRowFactory(tableRows), true)));
return false;
}
@Override
protected void done() {
super.done();
setColumnWidths();
}
}.execute();
}
private void setColumnWidths() {
int margin = 4;
int padding = 8;
// find the maximum width needed to fit the values for the first N rows, at most
final int rows = Math.min(20, outline.getRowCount());
for (int col = 1; col < outline.getColumnCount(); col++) {
int columnWidthLimit = 500;
int columnWidth = 50;
for (int row = 0; row < rows; row++) {
TableCellRenderer renderer = outline.getCellRenderer(row, col);
Component comp = outline.prepareRenderer(renderer, row, col);
columnWidth = Math.max(comp.getPreferredSize().width, columnWidth);
}
columnWidth += 2 * margin + padding; // add margin and regular padding
columnWidth = Math.min(columnWidth, columnWidthLimit);
outline.getColumnModel().getColumn(col).setPreferredWidth(columnWidth);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.BorderLayout());
}// </editor-fold>//GEN-END:initComponents
@Override
public ExplorerManager getExplorerManager() {
return explorerManager;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues> <AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -16,22 +16,27 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jHdrPanel" alignment="0" max="32767" attributes="0"/> <Component id="jHdrPanel" max="32767" attributes="0"/>
<Component id="jTableDataPanel" alignment="0" max="32767" attributes="0"/> <Component id="jTableDataPanel" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jHdrPanel" min="-2" max="-2" attributes="0"/> <Component id="jHdrPanel" min="-2" pref="53" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="jTableDataPanel" max="32767" attributes="0"/> <Component id="jTableDataPanel" pref="317" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="jHdrPanel"> <Container class="javax.swing.JPanel" name="jHdrPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[536, 40]"/>
</Property>
</Properties>
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
@ -39,11 +44,23 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="tablesDropdownList" min="-2" pref="130" max="-2" attributes="0"/> <Component id="tablesDropdownList" min="-2" pref="130" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="numEntriesField" min="-2" pref="71" max="-2" attributes="0"/> <Component id="numEntriesField" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace pref="130" max="32767" attributes="0"/> <EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="currPageLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="numPagesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="prevPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="nextPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace pref="133" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -51,12 +68,20 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="tablesDropdownList" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="nextPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="numEntriesField" alignment="3" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="3" attributes="0">
<Component id="tablesDropdownList" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numEntriesField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="currPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numPagesLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace pref="16" max="32767" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -97,57 +122,88 @@
<Border info="null"/> <Border info="null"/>
</Property> </Property>
</Properties> </Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="currPageLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.currPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="numPagesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.numPagesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="prevPageButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 0, 2, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="numEntriesFieldActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="prevPageButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="nextPageButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 0, 2, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nextPageButtonActionPerformed"/>
</Events> </Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="jTableDataPanel"> <Container class="javax.swing.JPanel" name="jTableDataPanel">
<Layout> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="275" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="jTable1">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="4" rowCount="4">
<Column editable="true" title="Title 1" type="java.lang.Object"/>
<Column editable="true" title="Title 2" type="java.lang.Object"/>
<Column editable="true" title="Title 3" type="java.lang.Object"/>
<Column editable="true" title="Title 4" type="java.lang.Object"/>
</Table>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -18,22 +18,29 @@
*/ */
package org.sleuthkit.autopsy.contentviewers; package org.sleuthkit.autopsy.contentviewers;
import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
@ -48,16 +55,22 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
private String tmpDBPathName = null; private String tmpDBPathName = null;
private File tmpDBFile = null; private File tmpDBFile = null;
// TBD: Change the value to be a Array of ColDefs private final Map<String, String> dbTablesMap = new TreeMap<>();
Map<String, String> dbTablesMap = new TreeMap<>();
private static final int ROWS_PER_PAGE = 100;
private int numRows; // num of rows in the selected table
private int currPage = 0; // curr page of rows being displayed
SQLiteTableView selectedTableView = new SQLiteTableView();
private SwingWorker<? extends Object, ? extends Object> worker;
/** /**
* Creates new form SQLiteViewer * Creates new form SQLiteViewer
*/ */
public SQLiteViewer() { public SQLiteViewer() {
initComponents(); initComponents();
jTableDataPanel.add(selectedTableView, BorderLayout.CENTER);
customizeComponents();
} }
/** /**
@ -73,9 +86,15 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
tablesDropdownList = new javax.swing.JComboBox<>(); tablesDropdownList = new javax.swing.JComboBox<>();
jLabel1 = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel();
numEntriesField = new javax.swing.JTextField(); numEntriesField = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
currPageLabel = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
numPagesLabel = new javax.swing.JLabel();
prevPageButton = new javax.swing.JButton();
nextPageButton = new javax.swing.JButton();
jTableDataPanel = new javax.swing.JPanel(); jTableDataPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable(); jHdrPanel.setPreferredSize(new java.awt.Dimension(536, 40));
tablesDropdownList.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); tablesDropdownList.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
tablesDropdownList.addActionListener(new java.awt.event.ActionListener() { tablesDropdownList.addActionListener(new java.awt.event.ActionListener() {
@ -89,9 +108,38 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
numEntriesField.setEditable(false); numEntriesField.setEditable(false);
numEntriesField.setText(org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numEntriesField.text")); // NOI18N numEntriesField.setText(org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numEntriesField.text")); // NOI18N
numEntriesField.setBorder(null); numEntriesField.setBorder(null);
numEntriesField.addActionListener(new java.awt.event.ActionListener() {
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel2.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(currPageLabel, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.currPageLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel3.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(numPagesLabel, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numPagesLabel.text")); // NOI18N
prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(prevPageButton, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.prevPageButton.text")); // NOI18N
prevPageButton.setBorderPainted(false);
prevPageButton.setContentAreaFilled(false);
prevPageButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
prevPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
prevPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
numEntriesFieldActionPerformed(evt); prevPageButtonActionPerformed(evt);
}
});
nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(nextPageButton, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.nextPageButton.text")); // NOI18N
nextPageButton.setBorderPainted(false);
nextPageButton.setContentAreaFilled(false);
nextPageButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
nextPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
nextPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextPageButtonActionPerformed(evt);
} }
}); });
@ -102,53 +150,44 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
.addGroup(jHdrPanelLayout.createSequentialGroup() .addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jLabel1) .addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(23, 23, 23) .addGap(18, 18, 18)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(130, Short.MAX_VALUE)) .addGap(15, 15, 15)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(currPageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(numPagesLabel)
.addGap(18, 18, 18)
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(133, Short.MAX_VALUE))
); );
jHdrPanelLayout.setVerticalGroup( jHdrPanelLayout.setVerticalGroup(
jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jHdrPanelLayout.createSequentialGroup() .addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1) .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addContainerGap(16, Short.MAX_VALUE)) .addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
); .addComponent(jLabel1)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
jTable1.setModel(new javax.swing.table.DefaultTableModel( .addComponent(jLabel2)
new Object [][] { .addComponent(currPageLabel)
{null, null, null, null}, .addComponent(jLabel3)
{null, null, null, null}, .addComponent(numPagesLabel)))
{null, null, null, null},
{null, null, null, null}
},
new String [] {
"Title 1", "Title 2", "Title 3", "Title 4"
}
));
jScrollPane1.setViewportView(jTable1);
javax.swing.GroupLayout jTableDataPanelLayout = new javax.swing.GroupLayout(jTableDataPanel);
jTableDataPanel.setLayout(jTableDataPanelLayout);
jTableDataPanelLayout.setHorizontalGroup(
jTableDataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jTableDataPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGap(15, 15, 15))
);
jTableDataPanelLayout.setVerticalGroup(
jTableDataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jTableDataPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE)
.addContainerGap()) .addContainerGap())
); );
jTableDataPanel.setLayout(new java.awt.BorderLayout());
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -159,34 +198,62 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jHdrPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jHdrPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGap(0, 0, 0)
.addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void numEntriesFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_numEntriesFieldActionPerformed private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_numEntriesFieldActionPerformed currPage++;
if (currPage * ROWS_PER_PAGE > numRows) {
nextPageButton.setEnabled(false);
}
currPageLabel.setText(Integer.toString(currPage));
prevPageButton.setEnabled(true);
// read and display a page of rows
String tableName = (String) this.tablesDropdownList.getSelectedItem();
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
}//GEN-LAST:event_nextPageButtonActionPerformed
private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
currPage--;
if (currPage == 1) {
prevPageButton.setEnabled(false);
}
currPageLabel.setText(Integer.toString(currPage));
nextPageButton.setEnabled(true);
// read and display a page of rows
String tableName = (String) this.tablesDropdownList.getSelectedItem();
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
}//GEN-LAST:event_prevPageButtonActionPerformed
private void tablesDropdownListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tablesDropdownListActionPerformed private void tablesDropdownListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tablesDropdownListActionPerformed
JComboBox<String> cb = (JComboBox<String>) evt.getSource(); JComboBox<?> cb = (JComboBox<?>) evt.getSource();
String tableName = (String) cb.getSelectedItem(); String tableName = (String) cb.getSelectedItem();
if (null == tableName) { if (null == tableName) {
return; return;
} }
readTable(tableName); selectTable(tableName);
}//GEN-LAST:event_tablesDropdownListActionPerformed }//GEN-LAST:event_tablesDropdownListActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel currPageLabel;
private javax.swing.JPanel jHdrPanel; private javax.swing.JPanel jHdrPanel;
private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel jLabel2;
private javax.swing.JTable jTable1; private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jTableDataPanel; private javax.swing.JPanel jTableDataPanel;
private javax.swing.JButton nextPageButton;
private javax.swing.JTextField numEntriesField; private javax.swing.JTextField numEntriesField;
private javax.swing.JLabel numPagesLabel;
private javax.swing.JButton prevPageButton;
private javax.swing.JComboBox<String> tablesDropdownList; private javax.swing.JComboBox<String> tablesDropdownList;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ -231,11 +298,6 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
} }
} }
private void customizeComponents() {
// add a actionListener to jTablesComboBox
}
/** /**
* Process the given SQLite DB file * Process the given SQLite DB file
* *
@ -315,41 +377,27 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
String tableSQL = resultSet.getString("sql"); //NON-NLS String tableSQL = resultSet.getString("sql"); //NON-NLS
dbTablesMap.put(tableName, tableSQL); dbTablesMap.put(tableName, tableSQL);
String query = "PRAGMA table_info(" + tableName + ")"; //NON-NLS
ResultSet rs2;
try {
Statement statement2 = connection.createStatement();
rs2 = statement2.executeQuery(query);
while (rs2.next()) {
// System.out.println("RAMAN: Col Name = " + rs2.getString("name"));
// System.out.println("RAMAN: Col Type = " + rs2.getString("type"));
// RAMAN TBD: parse and save the table schema
}
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "Error while trying to get columns from sqlite db." + connection, ex); //NON-NLS
}
} }
} catch (Exception e) { } catch (SQLException e) {
LOGGER.log(Level.SEVERE, "Error getting table names from the DB", e); //NON-NLS LOGGER.log(Level.SEVERE, "Error getting table names from the DB", e); //NON-NLS
} }
return true; return true;
} }
private void readTable(String tableName) { private void selectTable(String tableName) {
// TBD: need to handle cancelling if one is already in progress if (worker != null && !worker.isDone()) {
worker.cancel(false);
worker = null;
}
new SwingWorker<Integer, Void>() { worker = new SwingWorker<Integer, Void>() {
@Override @Override
protected Integer doInBackground() throws Exception { protected Integer doInBackground() throws Exception {
try { try {
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery( ResultSet resultSet = statement.executeQuery(
"SELECT COUNT(*) as count FROM " + tableName); //NON-NLS "SELECT count (*) as count FROM " + tableName); //NON-NLS
// TBD: read the rows here and popluate the ExplorerManager.
return resultSet.getInt("count"); return resultSet.getInt("count");
} catch (SQLException ex) { } catch (SQLException ex) {
@ -363,33 +411,104 @@ public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
protected void done() { protected void done() {
super.done(); super.done();
try { try {
int numRows = get();
numRows = get();
numEntriesField.setText(numRows + " entries"); numEntriesField.setText(numRows + " entries");
currPage = 1;
currPageLabel.setText(Integer.toString(currPage));
numPagesLabel.setText(Integer.toString((numRows / ROWS_PER_PAGE) + 1));
prevPageButton.setEnabled(false);
if (numRows > 0) {
nextPageButton.setEnabled(((numRows > ROWS_PER_PAGE)));
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
} else {
nextPageButton.setEnabled(false);
selectedTableView.setupTable(Collections.emptyList());
}
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while reading table.", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Unexpected exception while reading table.", ex); //NON-NLS
} }
} }
}.execute(); };
worker.execute();
} }
enum SQLStorageClass { private void readTable(String tableName, int startRow, int numRowsToRead) {
NULL,
INTEGER,
REAL,
TEXT,
BLOB
};
private class SQLColDef { if (worker != null && !worker.isDone()) {
worker.cancel(false);
private final String colName; worker = null;
private final SQLStorageClass storageClass;
SQLColDef(String colName, SQLStorageClass sc) {
this.colName = colName;
this.storageClass = sc;
} }
worker = new SwingWorker<ArrayList<Map<String, Object>>, Void>() {
@Override
protected ArrayList<Map<String, Object>> doInBackground() throws Exception {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT * FROM " + tableName
+ " LIMIT " + Integer.toString(numRowsToRead)
+ " OFFSET " + Integer.toString(startRow - 1)
); //NON-NLS
return resultSetToArrayList(resultSet);
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to get data for table " + tableName, ex); //NON-NLS
}
//NON-NLS
return null;
}
@Override
protected void done() {
if (isCancelled()) {
return;
}
super.done();
try {
ArrayList<Map<String, Object>> rows = get();
if (Objects.nonNull(rows)) {
selectedTableView.setupTable(rows);
}else{
selectedTableView.setupTable(Collections.emptyList());
}
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while reading table " + tableName, ex); //NON-NLS
}
}
};
worker.execute();
}
@NbBundle.Messages("SQLiteViewer.BlobNotShown.message=BLOB Data not shown")
private ArrayList<Map<String, Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int columns = metaData.getColumnCount();
ArrayList<Map<String, Object>> rowlist = new ArrayList<>();
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<>(columns);
for (int i = 1; i <= columns; ++i) {
if (rs.getObject(i) == null) {
row.put(metaData.getColumnName(i), "");
} else {
if (metaData.getColumnTypeName(i).compareToIgnoreCase("blob") == 0) {
row.put(metaData.getColumnName(i), Bundle.SQLiteViewer_BlobNotShown_message());
} else {
row.put(metaData.getColumnName(i), rs.getObject(i));
}
}
}
rowlist.add(row);
}
return rowlist;
} }
} }

View File

@ -198,10 +198,10 @@
<file name="org-openide-actions-ToolsAction.shadow_hidden"/> <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
<file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.shadow"> <file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.shadow">
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/> <attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/>
<attr name="position" intvalue="200"/> <attr name="position" intvalue="104"/>
</file> </file>
<folder name="RunIngestModules"> <folder name="RunIngestModules">
<attr name="position" intvalue="201"/> <attr name="position" intvalue="105"/>
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.ingest.Bundle"/> <attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.ingest.Bundle"/>
<file name="org-sleuthkit-autopsy-ingest-RunIngestAction.shadow"> <file name="org-sleuthkit-autopsy-ingest-RunIngestAction.shadow">
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-ingest-RunIngestAction.instance"/> <attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-ingest-RunIngestAction.instance"/>
@ -213,7 +213,7 @@
</file>--> </file>-->
<file name="org-sleuthkit-autopsy-report-ReportWizardAction-separatorAfter.instance"> <file name="org-sleuthkit-autopsy-report-ReportWizardAction-separatorAfter.instance">
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/> <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
<attr name="position" intvalue="104"/> <attr name="position" intvalue="199"/>
</file> </file>
<!--<file name="Separator1.instance_hidden"/> <!--<file name="Separator1.instance_hidden"/>
<file name="Separator3.instance_hidden"/>--> <file name="Separator3.instance_hidden"/>-->

View File

@ -453,7 +453,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
return; return;
} }
Content content = (selectedNode).getLookup().lookup(Content.class); Content content = DataContentViewerUtility.getDefaultContent(selectedNode);
if (content == null) { if (content == null) {
resetComponent(); resetComponent();
return; return;

View File

@ -452,8 +452,7 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
return; return;
} }
Lookup lookup = selectedNode.getLookup(); Content content = DataContentViewerUtility.getDefaultContent(selectedNode);
Content content = lookup.lookup(Content.class);
if (content != null) { if (content != null) {
this.setDataView(content, 0); this.setDataView(content, 0);
return; return;

View File

@ -0,0 +1,54 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponents;
import org.sleuthkit.datamodel.Content;
import org.openide.nodes.Node;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* Utility classes for content viewers.
* In theory, this would live in the contentviewer package,
* but the initial method was needed only be viewers in
* corecomponents and therefore can stay out of public API.
*/
class DataContentViewerUtility {
/**
* Returns the first non-Blackboard Artifact from a Node.
* Needed for (at least) Hex and Strings that want to view
* all types of content (not just AbstractFile), but don't want
* to display an artifact unless that's the only thing there.
* Scenario is hash hit or interesting item hit.
*
* @param node Node passed into content viewer
* @return highest priority content or null if there is no content
*/
static Content getDefaultContent(Node node) {
Content bbContentSeen = null;
for (Content content : (node).getLookup().lookupAll(Content.class)) {
if (content instanceof BlackboardArtifact) {
bbContentSeen = content;
}
else {
return content;
}
}
return bbContentSeen;
}
}

View File

@ -202,7 +202,7 @@ public class ViewContextAction extends AbstractAction {
undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content));
TreeView treeView = treeViewTopComponent.getTree(); TreeView treeView = treeViewTopComponent.getTree();
treeView.expandNode(parentTreeViewNode); treeView.expandNode(parentTreeViewNode);
if (treeViewTopComponent.getSelectedNode().getDisplayName().equals(parentTreeViewNode.getDisplayName())) { if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) {
//In the case where our tree view already has the destination directory selected //In the case where our tree view already has the destination directory selected
//due to an optimization in the ExplorerManager.setExploredContextAndSelection method //due to an optimization in the ExplorerManager.setExploredContextAndSelection method
//the property change we listen for to call DirectoryTreeTopComponent.respondSelection //the property change we listen for to call DirectoryTreeTopComponent.respondSelection

View File

@ -19,22 +19,16 @@
package org.sleuthkit.autopsy.modules.filetypeid; package org.sleuthkit.autopsy.modules.filetypeid;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.apache.tika.io.TikaInputStream; import org.apache.tika.io.TikaInputStream;
import org.apache.tika.mime.MimeTypes; import org.apache.tika.mime.MimeTypes;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ReadContentInputStream; import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -278,52 +272,30 @@ public class FileTypeDetector {
} }
/** /**
* Determines whether or not the a file matches a user-defined custom file * Determines whether or not a file matches a user-defined custom file type.
* type. If the file matches and corresponds to an interesting files type
* rule, this method has the side effect of creating an interesting files
* hit artifact and indexing that artifact for keyword search.
* *
* @param file The file to test. * @param file The file to test.
* *
* @return The file type name string or null, if no match is detected. * @return The MIME type as a string if a match is found; otherwise null.
*
* @throws TskCoreException
*/ */
private String detectUserDefinedType(AbstractFile file) { private String detectUserDefinedType(AbstractFile file) {
String retValue = null;
for (FileType fileType : userDefinedFileTypes) { for (FileType fileType : userDefinedFileTypes) {
if (fileType.matches(file)) { if (fileType.matches(file)) {
if (fileType.createInterestingFileHit()) { retValue = fileType.getMimeType();
try { break;
BlackboardArtifact artifact;
artifact = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
Collection<BlackboardAttribute> attributes = new ArrayList<>();
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, FileTypeIdModuleFactory.getModuleName(), fileType.getInterestingFilesSetName());
attributes.add(setNameAttribute);
BlackboardAttribute ruleNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, FileTypeIdModuleFactory.getModuleName(), fileType.getMimeType());
attributes.add(ruleNameAttribute);
artifact.addAttributes(attributes);
try {
Case.getCurrentCase().getServices().getBlackboard().indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, String.format("Unable to index TSK_INTERESTING_FILE_HIT blackboard artifact %d (file obj_id=%d)", artifact.getArtifactID(), file.getId()), ex); //NON-NLS
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Unable to create TSK_INTERESTING_FILE_HIT artifact for file (obj_id=%d)", file.getId()), ex); //NON-NLS
}
}
return fileType.getMimeType();
} }
} }
return null; return retValue;
} }
/** /**
* Determines whether or not the a file matches a custom file type defined * Determines whether or not a file matches a custom file type defined by Autopsy.
* by Autopsy.
* *
* @param file The file to test. * @param file The file to test.
* *
* @return The file type name string or null, if no match is detected. * @return The MIME type as a string if a match is found; otherwise null.
*/ */
private String detectAutopsyDefinedType(AbstractFile file) { private String detectAutopsyDefinedType(AbstractFile file) {
for (FileType fileType : autopsyDefinedFileTypes) { for (FileType fileType : autopsyDefinedFileTypes) {
@ -395,7 +367,7 @@ public class FileTypeDetector {
* *
* @throws TskCoreException if detection is required and there is a problem * @throws TskCoreException if detection is required and there is a problem
* writing the result to the case database. * writing the result to the case database.
* @deprecated Use detectMIMEType instead, and call AbstractFile.setMIMEType * @deprecated Use getMIMEType instead, and call AbstractFile.setMIMEType
* and AbstractFile.save to save the result to the file object and the * and AbstractFile.save to save the result to the file object and the
* database. * database.
*/ */
@ -419,7 +391,7 @@ public class FileTypeDetector {
* @throws TskCoreException if detection is required and there is a problem * @throws TskCoreException if detection is required and there is a problem
* writing the result to the case database. * writing the result to the case database.
* *
* @deprecated Use detectMIMEType instead, and call AbstractFile.setMIMEType * @deprecated Use getMIMEType instead, and call AbstractFile.setMIMEType
* and AbstractFile.save to save the result to the file object and the * and AbstractFile.save to save the result to the file object and the
* database. * database.
*/ */
@ -441,7 +413,7 @@ public class FileTypeDetector {
* were uncertain, octet-stream is returned. * were uncertain, octet-stream is returned.
* *
* @throws TskCoreException * @throws TskCoreException
* @deprecated Use detectMIMEType instead. * @deprecated Use getMIMEType instead.
*/ */
@Deprecated @Deprecated
public String detect(AbstractFile file) throws TskCoreException { public String detect(AbstractFile file) throws TskCoreException {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2015 Basis Technology Corp. * Copyright 2013-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,9 +18,14 @@
*/ */
package org.sleuthkit.autopsy.modules.filetypeid; package org.sleuthkit.autopsy.modules.filetypeid;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.FileIngestModule; import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestJobContext;
@ -29,13 +34,16 @@ import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult; import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter; import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Detects the type of a file based on signature (magic) values. Posts results * Detects the type of a file based on signature (magic) values. Posts results
* to the blackboard. * to the blackboard.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"CannotRunFileTypeDetection=Unable to run file type detection." "CannotRunFileTypeDetection=Unable to run file type detection."
}) })
public class FileTypeIdIngestModule implements FileIngestModule { public class FileTypeIdIngestModule implements FileIngestModule {
@ -91,7 +99,12 @@ public class FileTypeIdIngestModule implements FileIngestModule {
*/ */
try { try {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
fileTypeDetector.getMIMEType(file); String mimeType = fileTypeDetector.getMIMEType(file);
file.setMIMEType(mimeType);
FileType fileType = detectUserDefinedFileType(file);
if (fileType != null && fileType.createInterestingFileHit()) {
createInterestingFileHit(file, fileType);
}
addToTotals(jobId, (System.currentTimeMillis() - startTime)); addToTotals(jobId, (System.currentTimeMillis() - startTime));
return ProcessResult.OK; return ProcessResult.OK;
} catch (Exception e) { } catch (Exception e) {
@ -100,6 +113,57 @@ public class FileTypeIdIngestModule implements FileIngestModule {
} }
} }
/**
* Determines whether or not a file matches a user-defined custom file type.
*
* @param file The file to test.
*
* @return The file type if a match is found; otherwise null.
*
* @throws CustomFileTypesException If there is an issue getting an instance
* of CustomFileTypesManager.
*/
private FileType detectUserDefinedFileType(AbstractFile file) throws CustomFileTypesManager.CustomFileTypesException {
FileType retValue = null;
CustomFileTypesManager customFileTypesManager = CustomFileTypesManager.getInstance();
List<FileType> fileTypesList = customFileTypesManager.getUserDefinedFileTypes();
for (FileType fileType : fileTypesList) {
if (fileType.matches(file)) {
retValue = fileType;
break;
}
}
return retValue;
}
/**
* Create an Interesting File hit using the specified file type rule.
*
* @param file The file from which to generate an artifact.
* @param fileType The file type rule for categorizing the hit.
*/
private void createInterestingFileHit(AbstractFile file, FileType fileType) {
try {
BlackboardArtifact artifact;
artifact = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
Collection<BlackboardAttribute> attributes = new ArrayList<>();
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, FileTypeIdModuleFactory.getModuleName(), fileType.getInterestingFilesSetName());
attributes.add(setNameAttribute);
BlackboardAttribute ruleNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, FileTypeIdModuleFactory.getModuleName(), fileType.getMimeType());
attributes.add(ruleNameAttribute);
artifact.addAttributes(attributes);
try {
Case.getCurrentCase().getServices().getBlackboard().indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, String.format("Unable to index TSK_INTERESTING_FILE_HIT blackboard artifact %d (file obj_id=%d)", artifact.getArtifactID(), file.getId()), ex); //NON-NLS
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Unable to create TSK_INTERESTING_FILE_HIT artifact for file (obj_id=%d)", file.getId()), ex); //NON-NLS
}
}
@Override @Override
public void shutDown() { public void shutDown() {
/** /**

View File

@ -1232,9 +1232,10 @@ public class HashDbManager implements PropertyChangeListener {
} else { } else {
type = TskData.FileKnown.KNOWN; type = TskData.FileKnown.KNOWN;
} }
EamGlobalFileInstance fileInstance = new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
type, comment);
try{ try{
EamGlobalFileInstance fileInstance = new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
type, comment);
EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID)); EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
} catch (EamDbException ex){ } catch (EamDbException ex){
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex); throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
@ -1260,7 +1261,11 @@ public class HashDbManager implements PropertyChangeListener {
} else { } else {
type = TskData.FileKnown.KNOWN; type = TskData.FileKnown.KNOWN;
} }
globalFileInstances.add(new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment())); try {
globalFileInstances.add(new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment()));
} catch (EamDbException ex){
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
}
} }
try{ try{

View File

@ -34,6 +34,7 @@ class ReportExcel implements TableReportModule {
private static final Logger logger = Logger.getLogger(ReportExcel.class.getName()); private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
private static ReportExcel instance; private static ReportExcel instance;
private static final int EXCEL_CELL_MAXIMUM_SIZE = 36767; //Specified at:https://poi.apache.org/apidocs/org/apache/poi/ss/SpreadsheetVersion.html
private Workbook wb; private Workbook wb;
private Sheet sheet; private Sheet sheet;
@ -236,10 +237,24 @@ class ReportExcel implements TableReportModule {
* @param row cells to add * @param row cells to add
*/ */
@Override @Override
@NbBundle.Messages({
"ReportExcel.exceptionMessage.dataTooLarge=Value is too long to fit into an Excel cell. ",
"ReportExcel.exceptionMessage.errorText=Error showing data into an Excel cell."
})
public void addRow(List<String> rowData) { public void addRow(List<String> rowData) {
Row row = sheet.createRow(rowIndex); Row row = sheet.createRow(rowIndex);
for (int i = 0; i < rowData.size(); ++i) { for (int i = 0; i < rowData.size(); ++i) {
row.createCell(i).setCellValue(rowData.get(i)); Cell excelCell = row.createCell(i);
try {
excelCell.setCellValue(rowData.get(i));
} catch (Exception e) {
if (e instanceof java.lang.IllegalArgumentException && rowData.get(i).length() > EXCEL_CELL_MAXIMUM_SIZE) {
excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_dataTooLarge() + e.getMessage());
} else {
excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_errorText());
}
}
} }
++rowIndex; ++rowIndex;
} }

View File

@ -51,6 +51,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Services; import org.sleuthkit.autopsy.casemodule.services.Services;
import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor; import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
@ -554,7 +555,8 @@ class ReportHTML implements TableReportModule {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("\t<tr>\n"); //NON-NLS builder.append("\t<tr>\n"); //NON-NLS
for (String cell : row) { for (String cell : row) {
builder.append("\t\t<td>").append(cell).append("</td>\n"); //NON-NLS String escapeHTMLCell = EscapeUtil.escapeHtml(cell);
builder.append("\t\t<td>").append(escapeHTMLCell).append("</td>\n"); //NON-NLS
} }
builder.append("\t</tr>\n"); //NON-NLS builder.append("\t</tr>\n"); //NON-NLS
rowCount++; rowCount++;

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-16 Basis Technology Corp. * Copyright 2013-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -40,7 +40,6 @@ import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
@ -666,8 +665,7 @@ class TableReportGenerator {
tableModule.startTable(columnHeaderNames); tableModule.startTable(columnHeaderNames);
} }
String previewreplace = EscapeUtil.escapeHtml(preview); tableModule.addRow(Arrays.asList(new String[]{preview, uniquePath, tagsList}));
tableModule.addRow(Arrays.asList(new String[]{previewreplace.replaceAll("<!", ""), uniquePath, tagsList}));
} }
// Finish the current data type // Finish the current data type

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2017 Basis Technology Corp. * Copyright 2017-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -28,13 +28,14 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.experimental.autoingest.AutoIngestDashboardOpenAction") @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.experimental.autoingest.AutoIngestDashboardOpenAction")
@ActionReference(path = "Menu/Tools", position = 104) @ActionReference(path = "Menu/Tools", position = 201)
@ActionRegistration(displayName = "#CTL_AutoIngestDashboardOpenAction", lazy = false) @ActionRegistration(displayName = "#CTL_AutoIngestDashboardOpenAction", lazy = false)
@Messages({"CTL_AutoIngestDashboardOpenAction=Auto Ingest Dashboard"}) @Messages({"CTL_AutoIngestDashboardOpenAction=Auto Ingest Dashboard"})
public final class AutoIngestDashboardOpenAction extends CallableSystemAction { public final class AutoIngestDashboardOpenAction extends CallableSystemAction {
private static final Logger LOGGER = Logger.getLogger(AutoIngestDashboardOpenAction.class.getName()); private static final Logger LOGGER = Logger.getLogger(AutoIngestDashboardOpenAction.class.getName());
private static final String DISPLAY_NAME = Bundle.CTL_AutoIngestDashboardOpenAction(); private static final String DISPLAY_NAME = Bundle.CTL_AutoIngestDashboardOpenAction();
private static final long serialVersionUID = 1L;
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -284,15 +284,6 @@ class AccountsText implements IndexedText {
} }
@Override @Override
@NbBundle.Messages({"AccountsText.getMarkup.noMatchMsg="
+ "<html><pre><span style\\\\='background\\\\:yellow'>There were no keyword hits on this page. <br />"
+ "The keyword could have been in the file name."
+ " <br />Advance to another page if present, or to view the original text, choose File Text"
+ " <br />in the drop down menu to the right...</span></pre></html>",
"AccountsText.getMarkup.queryFailedMsg="
+ "<html><pre><span style\\\\='background\\\\:yellow'>Failed to retrieve keyword hit results."
+ " <br />Confirm that Autopsy can connect to the Solr server. "
+ "<br /></span></pre></html>"})
public String getText() { public String getText() {
try { try {
loadPageInfo(); //inits once loadPageInfo(); //inits once
@ -321,7 +312,7 @@ class AccountsText implements IndexedText {
return "<html><pre>" + highlightedText + "</pre></html>"; //NON-NLS return "<html><pre>" + highlightedText + "</pre></html>"; //NON-NLS
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + this.solrObjectId + ", chunkID " + this.currentPage, ex); //NON-NLS logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + this.solrObjectId + ", chunkID " + this.currentPage, ex); //NON-NLS
return Bundle.AccountsText_getMarkup_queryFailedMsg(); return Bundle.IndexedText_errorMessage_errorGettingText();
} }
} }

View File

@ -54,11 +54,6 @@ AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in inde
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html> AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html>
ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer. ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer.
ExtractedContentViewer.getTitle=Indexed Text ExtractedContentViewer.getTitle=Indexed Text
ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0} is a known file (based on MD5 hash) and does not have text in the index.</p>
ExtractedContentViewer.getSolrContent.noTxtYetMsg=<p style\=''font-style\:italic''>{0} does not have text in the index.<br/>It may have no text, not been analyzed yet, or keyword search was not enabled during ingest.</p>
ExtractedContentViewer.getSolrContent.txtBodyItal=<span style\=''font-style\:italic''>{0}</span>
HighlightedMatchesSource.getMarkup.noMatchMsg=<span>Failed to retrieve indexed text for keyword hit. Advance to another page if present, or to view the&#10;original text, choose File Text in the drop down menu to the right.&#10;&#10;Alternatively, you may choose to extract file content and search for the hit using an external&#10;application (e.g. a text editor).</span>
HighlightedMatchesSource.getMarkup.queryFailedMsg=<html><pre><span style\\\\\='background\\\\\:yellow'>Failed to retrieve keyword hit results. <br />Confirm that Autopsy can connect to the Solr server. <br /></span></pre></html>
HighlightedMatchesSource.toString=Search Results HighlightedMatchesSource.toString=Search Results
Installer.reportPortError=Indexing server port {0} is not available. Check if your security software does not block {1} and consider changing {2} in {3} property file in the application user folder. Then try rebooting your system if another process was causing the conflict. Installer.reportPortError=Indexing server port {0} is not available. Check if your security software does not block {1} and consider changing {2} in {3} property file in the application user folder. Then try rebooting your system if another process was causing the conflict.
Installer.reportStopPortError=Indexing server stop port {0} is not available. Consider changing {1} in {2} property file in the application user folder. Installer.reportStopPortError=Indexing server stop port {0} is not available. Consider changing {1} in {2} property file in the application user folder.
@ -272,7 +267,6 @@ KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=No periodic searche
SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number. SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number.
SolrConnectionCheck.Hostname=Invalid hostname. SolrConnectionCheck.Hostname=Invalid hostname.
SolrConnectionCheck.MissingHostname=Missing hostname. SolrConnectionCheck.MissingHostname=Missing hostname.
RawText.getText.error.msg=Error getting text
GlobalListsManagementPanel.newListButton.text=New List GlobalListsManagementPanel.newListButton.text=New List
GlobalListsManagementPanel.importButton.text=Import List GlobalListsManagementPanel.importButton.text=Import List
GlobalListsManagementPanel.keywordListsLabel.text=Keyword Lists: GlobalListsManagementPanel.keywordListsLabel.text=Keyword Lists:

View File

@ -46,7 +46,6 @@ AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>\u30a4\u30f3\u30c7\u3
ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>\u30c6\u30ad\u30b9\u30c8\u30ed\u30fc\u30c9\u4e2d...\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002</span> ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>\u30c6\u30ad\u30b9\u30c8\u30ed\u30fc\u30c9\u4e2d...\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002</span>
ExtractedContentViewer.toolTip=\u30d5\u30a1\u30a4\u30eb\u3084\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u304b\u3089\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a\u3002\u3053\u306e\u30d3\u30e5\u30fc\u30a2\u3092\u6709\u52b9\u5316\u3059\u308b\u306b\u306f\u3001\u30d5\u30a1\u30a4\u30eb\u306b\u5bfe\u3057\u3066\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 ExtractedContentViewer.toolTip=\u30d5\u30a1\u30a4\u30eb\u3084\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u304b\u3089\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a\u3002\u3053\u306e\u30d3\u30e5\u30fc\u30a2\u3092\u6709\u52b9\u5316\u3059\u308b\u306b\u306f\u3001\u30d5\u30a1\u30a4\u30eb\u306b\u5bfe\u3057\u3066\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
ExtractedContentViewer.getTitle=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8 ExtractedContentViewer.getTitle=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8
ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0}\u306f\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\u3067\u3059\uff08MDS\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u3068\uff09\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002</p>
ExtractedContentViewer.getSolrContent.noTxtYetMsg=<p style\=''font-style\:italic''>{0}\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br/>\u30c6\u30ad\u30b9\u30c8\u304c\u7121\u3044\u304b\u3001\u307e\u3060\u89e3\u6790\u3055\u308c\u3066\u3044\u306a\u3044\u304b\u3001\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u304c\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306b\u6709\u52b9\u5316\u3055\u308c\u3066\u3044\u306a\u304b\u3063\u305f\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002</p> ExtractedContentViewer.getSolrContent.noTxtYetMsg=<p style\=''font-style\:italic''>{0}\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br/>\u30c6\u30ad\u30b9\u30c8\u304c\u7121\u3044\u304b\u3001\u307e\u3060\u89e3\u6790\u3055\u308c\u3066\u3044\u306a\u3044\u304b\u3001\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u304c\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306b\u6709\u52b9\u5316\u3055\u308c\u3066\u3044\u306a\u304b\u3063\u305f\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002</p>
HighlightedMatchesSource.toString=\u691c\u7d22\u7d50\u679c HighlightedMatchesSource.toString=\u691c\u7d22\u7d50\u679c
Installer.reportPortError=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b5\u30fc\u30d0\u30fc\u30dd\u30fc\u30c8 {0} \u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002\u4f7f\u7528\u3057\u3066\u3044\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u304c {1} \u3092\u30d6\u30ed\u30c3\u30af\u3057\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30e6\u30fc\u30b6\u30fc\u30d5\u30a9\u30eb\u30c0\u30fc\u5185\u306e{3}\u30d7\u30ed\u30d1\u30c6\u30a3\u30d5\u30a1\u30a4\u30eb\u306e{2}\u3092\u5909\u66f4\u3059\u308b\u691c\u8a0e\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3082\u3057\u4ed6\u306e\u51e6\u7406\u304c\u554f\u984c\u306e\u539f\u56e0\u3067\u3042\u308c\u3070\u3001\u30b7\u30b9\u30c6\u30e0\u3092\u518d\u8d77\u52d5\u3057\u3066\u4e0b\u3055\u3044\u3002 Installer.reportPortError=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b5\u30fc\u30d0\u30fc\u30dd\u30fc\u30c8 {0} \u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002\u4f7f\u7528\u3057\u3066\u3044\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u304c {1} \u3092\u30d6\u30ed\u30c3\u30af\u3057\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30e6\u30fc\u30b6\u30fc\u30d5\u30a9\u30eb\u30c0\u30fc\u5185\u306e{3}\u30d7\u30ed\u30d1\u30c6\u30a3\u30d5\u30a1\u30a4\u30eb\u306e{2}\u3092\u5909\u66f4\u3059\u308b\u691c\u8a0e\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3082\u3057\u4ed6\u306e\u51e6\u7406\u304c\u554f\u984c\u306e\u539f\u56e0\u3067\u3042\u308c\u3070\u3001\u30b7\u30b9\u30c6\u30e0\u3092\u518d\u8d77\u52d5\u3057\u3066\u4e0b\u3055\u3044\u3002
@ -200,7 +199,6 @@ KeywordSearchIngestModule.doInBackGround.finalizeMsg=- \u6700\u7d42\u51e6\u7406\
KeywordSearchIngestModule.doInBackGround.pendingMsg=\uff08\u30da\u30f3\u30c7\u30a3\u30f3\u30b0\uff09 KeywordSearchIngestModule.doInBackGround.pendingMsg=\uff08\u30da\u30f3\u30c7\u30a3\u30f3\u30b0\uff09
SearchRunner.doInBackGround.cancelMsg=\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09 SearchRunner.doInBackGround.cancelMsg=\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
Server.addDoc.exception.msg2=\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u4f7f\u7528\u3057\u307e\u3057\u305f\u304c\u3001\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u6b21\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0} Server.addDoc.exception.msg2=\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u4f7f\u7528\u3057\u307e\u3057\u305f\u304c\u3001\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u6b21\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0}
ExtractedContentViewer.getSolrContent.txtBodyItal=<span style\=''font-style\:italic''>{0}</span>
KeywordSearchJobSettingsPanel.keywordSearchEncodings.text=- KeywordSearchJobSettingsPanel.keywordSearchEncodings.text=-
KeywordSearchJobSettingsPanel.languagesValLabel.text=- KeywordSearchJobSettingsPanel.languagesValLabel.text=-
KeywordSearchJobSettingsPanel.encodingsLabel.text=\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\uff1a KeywordSearchJobSettingsPanel.encodingsLabel.text=\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\uff1a
@ -261,7 +259,6 @@ KeywordSearchModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\
SearchRunner.Searcher.done.err.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u3092\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f SearchRunner.Searcher.done.err.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u3092\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=\u5b9a\u671f\u7684\u691c\u7d22\u7121\u3057 KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=\u5b9a\u671f\u7684\u691c\u7d22\u7121\u3057
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=\u5168\u4f53\u7684\u306b\u4e00\u756a\u901f\u3044\u3067\u3059\u304c\u3001\u51e6\u7406\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093 KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=\u5168\u4f53\u7684\u306b\u4e00\u756a\u901f\u3044\u3067\u3059\u304c\u3001\u51e6\u7406\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093
HighlightedMatchesSource.getMarkup.queryFailedMsg=<html><pre><span style\\\\\='background\\\\\:yellow'>\u30ad\u30fc\u30ef\u30fc\u30c9\u306b\u30d2\u30c3\u30c8\u3057\u305f\u7d50\u679c\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br />Autopsy\u304cSolr\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002<br /></span></pre></html>\
KeywordSearch.openCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f KeywordSearch.openCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
KeywordSearch.closeCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u9589\u3058\u308b\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f KeywordSearch.closeCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u9589\u3058\u308b\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
KeywordSearchListsManagementPanel.fileExtensionFilterLb2=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30a8\u30f3\u30b1\u30fc\u30b9\u3059\u308b(txt) KeywordSearchListsManagementPanel.fileExtensionFilterLb2=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30a8\u30f3\u30b1\u30fc\u30b9\u3059\u308b(txt)
@ -272,7 +269,7 @@ SolrConnectionCheck.HostnameOrPort=hostname\u3084\u30dd\u30fc\u30c8\u756a\u53f7\
SolrConnectionCheck.Hostname=hostname\u304c\u7121\u52b9\u3067\u3059\u3002 SolrConnectionCheck.Hostname=hostname\u304c\u7121\u52b9\u3067\u3059\u3002
SolrConnectionCheck.Port=\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059\u3002 SolrConnectionCheck.Port=\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059\u3002
SolrConnectionCheck.MissingHostname=hostname\u304c\u6b20\u3051\u3066\u307e\u3059\u3002 SolrConnectionCheck.MissingHostname=hostname\u304c\u6b20\u3051\u3066\u307e\u3059\u3002
RawText.getText.error.msg=\u30c6\u30ad\u30b9\u30c8\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f ExtractedContentViewer.getText.error.msg=\u30c6\u30ad\u30b9\u30c8\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
GlobalListsManagementPanel.exportButton.text=\u30ea\u30b9\u30c8\u3092\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 GlobalListsManagementPanel.exportButton.text=\u30ea\u30b9\u30c8\u3092\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
GlobalListsManagementPanel.deleteListButton.text=\u30ea\u30b9\u30c8\u3092\u524a\u9664 GlobalListsManagementPanel.deleteListButton.text=\u30ea\u30b9\u30c8\u3092\u524a\u9664
GlobalListsManagementPanel.copyListButton.text=\u30ea\u30b9\u30c8\u3092\u30b3\u30d4\u30fc GlobalListsManagementPanel.copyListButton.text=\u30ea\u30b9\u30c8\u3092\u30b3\u30d4\u30fc

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-17 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -24,6 +24,7 @@ import java.awt.event.ActionListener;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JTextPane; import javax.swing.JTextPane;
@ -647,8 +648,6 @@ class ExtractedContentPanel extends javax.swing.JPanel {
return source.getText(); return source.getText();
} }
@NbBundle.Messages({
"ExtractedContentPanel.SetMarkup.error=There was an error getting the text for the selected source."})
@Override @Override
protected void done() { protected void done() {
super.done(); super.done();
@ -663,11 +662,9 @@ class ExtractedContentPanel extends javax.swing.JPanel {
setPanelText("", false); setPanelText("", false);
} }
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | CancellationException | ExecutionException ex) {
logger.log(Level.SEVERE, "Error getting marked up text", ex); //NON-NLS logger.log(Level.SEVERE, "Error getting marked up text", ex); //NON-NLS
setPanelText(Bundle.ExtractedContentPanel_SetMarkup_error(), true); setPanelText(Bundle.IndexedText_errorMessage_errorGettingText(), true);
} // catch and ignore if we were cancelled
catch (java.util.concurrent.CancellationException ex) {
} }
updateControls(source); updateControls(source);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -365,81 +365,84 @@ class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPa
chooser.addChoosableFileFilter(autopsyFilter); chooser.addChoosableFileFilter(autopsyFilter);
chooser.addChoosableFileFilter(encaseFilter); chooser.addChoosableFileFilter(encaseFilter);
chooser.setAcceptAllFileFilterUsed(false); chooser.setAcceptAllFileFilterUsed(false);
chooser.setMultiSelectionEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
String listName = null; String listName = null;
int returnVal = chooser.showOpenDialog(this); int returnVal = chooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) { if (returnVal == JFileChooser.APPROVE_OPTION) {
File selFile = chooser.getSelectedFile(); File[] selFiles = chooser.getSelectedFiles();
if (selFile == null) {
return;
}
//force append extension if not given for (File file : selFiles) {
String fileAbs = selFile.getAbsolutePath(); if (file == null) {
continue;
final KeywordSearchList reader;
if (KeywordSearchUtil.isXMLList(fileAbs)) {
reader = new XmlKeywordSearchList(fileAbs);
} else {
reader = new EnCaseKeywordSearchList(fileAbs);
}
if (!reader.load()) {
KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
return;
}
List<KeywordList> toImport = reader.getListsL();
List<KeywordList> toImportConfirmed = new ArrayList<>();
final XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent();
for (KeywordList list : toImport) {
//check name collisions
listName = list.getName();
if (writer.listExists(listName)) {
String[] options;
if (toImport.size() == 1) { //only give them cancel and yes buttons for single list imports
options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
} else {
options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
}
int choice = JOptionPane.showOptionDialog(this,
NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", listName),
NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"),
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (choice == JOptionPane.OK_OPTION) {
toImportConfirmed.add(list);
} else if (choice == JOptionPane.CANCEL_OPTION) {
break;
}
} else {
//no conflict
toImportConfirmed.add(list);
} }
} //force append extension if not given
String fileAbs = file.getAbsolutePath();
final KeywordSearchList reader;
if (toImportConfirmed.isEmpty()) { if (KeywordSearchUtil.isXMLList(fileAbs)) {
return; reader = new XmlKeywordSearchList(fileAbs);
} } else {
reader = new EnCaseKeywordSearchList(fileAbs);
}
if (!writer.writeLists(toImportConfirmed)) { if (!reader.load()) {
KeywordSearchUtil.displayDialog( KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
return;
}
List<KeywordList> toImport = reader.getListsL();
List<KeywordList> toImportConfirmed = new ArrayList<>();
final XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent();
for (KeywordList list : toImport) {
//check name collisions
listName = list.getName();
if (writer.listExists(listName)) {
String[] options;
if (toImport.size() == 1) { //only give them cancel and yes buttons for single list imports
options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
} else {
options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
}
int choice = JOptionPane.showOptionDialog(this,
NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", listName),
NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"),
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (choice == JOptionPane.OK_OPTION) {
toImportConfirmed.add(list);
} else if (choice == JOptionPane.CANCEL_OPTION) {
break;
}
} else {
//no conflict
toImportConfirmed.add(list);
}
}
if (toImportConfirmed.isEmpty()) {
return;
}
if (!writer.writeLists(toImportConfirmed)) {
KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY, file.getParent());
} }
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY, selFile.getParent());
} }
tableModel.resync(); tableModel.resync();

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.keywordsearch;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet; import com.google.common.collect.TreeRangeSet;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -41,7 +40,6 @@ import org.apache.solr.client.solrj.SolrRequest.METHOD;
import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrDocumentList;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.keywordsearch.KeywordQueryFilter.FilterType; import org.sleuthkit.autopsy.keywordsearch.KeywordQueryFilter.FilterType;
@ -104,13 +102,13 @@ class HighlightedText implements IndexedText {
/** /**
* This constructor is used when keyword hits are accessed from the ad-hoc * This constructor is used when keyword hits are accessed from the ad-hoc
* search results. In that case we have the entire QueryResults object and * search results. In that case we have the entire QueryResults object and
need to arrange the paging. * need to arrange the paging.
* *
* @param objectId The objectID of the content whose text will be * @param objectId The objectID of the content whose text will be
* highlighted. * highlighted.
* @param QueryResults The QueryResults for the ad-hoc search from whose * @param QueryResults The QueryResults for the ad-hoc search from whose
results a selection was made leading to this * results a selection was made leading to this
HighlightedText. * HighlightedText.
*/ */
HighlightedText(long objectId, QueryResults hits) { HighlightedText(long objectId, QueryResults hits) {
this.objectId = objectId; this.objectId = objectId;
@ -140,7 +138,6 @@ class HighlightedText implements IndexedText {
* This method figures out which pages / chunks have hits. Invoking it a * This method figures out which pages / chunks have hits. Invoking it a
* second time has no effect. * second time has no effect.
*/ */
@Messages({"HighlightedText.query.exception.msg=Could not perform the query to get chunk info and get highlights:"})
synchronized private void loadPageInfo() throws TskCoreException, KeywordSearchModuleException, NoOpenCoreException { synchronized private void loadPageInfo() throws TskCoreException, KeywordSearchModuleException, NoOpenCoreException {
if (isPageInfoLoaded) { if (isPageInfoLoaded) {
return; return;
@ -158,7 +155,6 @@ class HighlightedText implements IndexedText {
this.numberPages = 1; this.numberPages = 1;
this.currentPage = 1; this.currentPage = 1;
numberOfHitsPerPage.put(1, 0); numberOfHitsPerPage.put(1, 0);
pages.add(1);
currentHitPerPage.put(1, 0); currentHitPerPage.put(1, 0);
isPageInfoLoaded = true; isPageInfoLoaded = true;
} }
@ -207,10 +203,10 @@ class HighlightedText implements IndexedText {
isLiteral = hits.getQuery().isLiteral(); isLiteral = hits.getQuery().isLiteral();
/** /**
* Organize the hits by page, filter as needed. * Organize the hits by page, filter as needed. We process *every*
* We process *every* keyword here because in the case of a regular * keyword here because in the case of a regular expression search there
* expression search there may be multiple different keyword * may be multiple different keyword hits located in different chunks
* hits located in different chunks for the same file/artifact. * for the same file/artifact.
*/ */
for (Keyword k : hits.getKeywords()) { for (Keyword k : hits.getKeywords()) {
for (KeywordHit hit : hits.getResults(k)) { for (KeywordHit hit : hits.getResults(k)) {
@ -428,7 +424,7 @@ class HighlightedText implements IndexedText {
return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS
} catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) { } catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + objectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + objectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS
return NbBundle.getMessage(this.getClass(), "HighlightedMatchesSource.getMarkup.queryFailedMsg"); return Bundle.IndexedText_errorMessage_errorGettingText();
} }
} }
@ -466,12 +462,13 @@ class HighlightedText implements IndexedText {
* to a Solr query. We expect there to only ever be * to a Solr query. We expect there to only ever be
* a single document. * a single document.
* *
* @return Either a string with the keyword highlighted via HTML span tags or a string * @return Either a string with the keyword highlighted via HTML span tags
* indicating that we did not find a hit in the document. * or a string indicating that we did not find a hit in the
* document.
*/ */
static String attemptManualHighlighting(SolrDocumentList solrDocumentList, String highlightField, Collection<String> keywords) { static String attemptManualHighlighting(SolrDocumentList solrDocumentList, String highlightField, Collection<String> keywords) {
if (solrDocumentList.isEmpty()) { if (solrDocumentList.isEmpty()) {
return NbBundle.getMessage(HighlightedText.class, "HighlightedMatchesSource.getMarkup.noMatchMsg"); return Bundle.IndexedText_errorMessage_errorGettingText();
} }
// It doesn't make sense for there to be more than a single document in // It doesn't make sense for there to be more than a single document in

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,12 +18,19 @@
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import org.openide.util.NbBundle;
/** /**
* Interface to provide HTML text to display in ExtractedContentViewer. There is * Interface to provide HTML text to display in ExtractedContentViewer. There is
* a SOLR implementation of this that interfaces with SOLR to highlight the * a SOLR implementation of this that interfaces with SOLR to highlight the
* keyword hits and a version that does not do markup so that you can simply * keyword hits and a version that does not do markup so that you can simply
* view the stored text. * view the stored text.
*/ */
@NbBundle.Messages({
"IndexedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving indexed text.</span>",
"IndexedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>",
"IndexedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No indexed text for this file.</span>"
})
interface IndexedText { interface IndexedText {
/** /**

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,7 +18,6 @@
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.util.LinkedHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.SolrServerException;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
@ -153,10 +152,10 @@ class RawText implements IndexedText {
} else if (this.blackboardArtifact != null) { } else if (this.blackboardArtifact != null) {
return getArtifactText(); return getArtifactText();
} }
} catch (SolrServerException ex) { } catch (SolrServerException | NoOpenCoreException ex) {
logger.log(Level.SEVERE, "Couldn't get extracted content", ex); //NON-NLS logger.log(Level.SEVERE, "Couldn't get extracted text", ex); //NON-NLS
} }
return NbBundle.getMessage(this.getClass(), "RawText.getText.error.msg"); return Bundle.IndexedText_errorMessage_errorGettingText();
} }
@NbBundle.Messages({ @NbBundle.Messages({
@ -186,7 +185,6 @@ class RawText implements IndexedText {
return 0; return 0;
} }
@Override @Override
public int getNumberPages() { public int getNumberPages() {
return numPages; return numPages;
@ -207,11 +205,8 @@ class RawText implements IndexedText {
} else { } else {
hasChunks = true; hasChunks = true;
} }
} catch (KeywordSearchModuleException ex) { } catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of chunks: ", ex); //NON-NLS logger.log(Level.SEVERE, "Could not get number of chunks: ", ex); //NON-NLS
} catch (NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of chunks: ", ex); //NON-NLS
} }
} }
@ -225,31 +220,32 @@ class RawText implements IndexedText {
* chunks. This means we need to address the content * chunks. This means we need to address the content
* pages specially. * pages specially.
* *
* @return the extracted content * @return the extracted text
* *
* @throws SolrServerException if something goes wrong * @throws NoOpenCoreException If no Solr core is available.
* @throws SolrServerException If there's a Solr communication or parsing
* issue.
*/ */
private String getContentText(int currentPage, boolean hasChunks) throws SolrServerException { private String getContentText(int currentPage, boolean hasChunks) throws NoOpenCoreException, SolrServerException {
final Server solrServer = KeywordSearch.getServer(); final Server solrServer = KeywordSearch.getServer();
if (hasChunks == false) { if (hasChunks == false) {
//if no chunks, it is safe to assume there is no text content //if no chunks, it is safe to assume there is no text content
//because we are storing extracted text in chunks only //because we are storing extracted text in chunks only
//and the non-chunk stores meta-data only //and the non-chunk stores meta-data only
String name = content.getName();
String msg = null; String msg = null;
if (content instanceof AbstractFile) { if (content instanceof AbstractFile) {
//we know it's AbstractFile, but do quick check to make sure if we index other objects in future //we know it's AbstractFile, but do quick check to make sure if we index other objects in future
boolean isKnown = TskData.FileKnown.KNOWN.equals(((AbstractFile) content).getKnown()); boolean isKnown = TskData.FileKnown.KNOWN.equals(((AbstractFile) content).getKnown());
if (isKnown && KeywordSearchSettings.getSkipKnown()) { if (isKnown && KeywordSearchSettings.getSkipKnown()) {
msg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.knownFileMsg", name); msg = Bundle.IndexedText_warningMessage_knownFile();
} }
} }
if (msg == null) { if (msg == null) {
msg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.noTxtYetMsg", name); msg = Bundle.IndexedText_warningMessage_noTextAvailable();
} }
String htmlMsg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.txtBodyItal", msg); return msg;
return htmlMsg;
} }
int chunkId = currentPage; int chunkId = currentPage;
@ -262,33 +258,46 @@ class RawText implements IndexedText {
} }
//not cached //not cached
try { String indexedText = solrServer.getSolrContent(this.objectId, chunkId);
String indexedText = solrServer.getSolrContent(this.objectId, chunkId); if (indexedText == null) {
if (indexedText == null) indexedText = ""; if (content instanceof AbstractFile) {
cachedString = EscapeUtil.escapeHtml(indexedText).trim(); return Bundle.IndexedText_errorMessage_errorGettingText();
StringBuilder sb = new StringBuilder(cachedString.length() + 20); } else {
sb.append("<pre>").append(cachedString).append("</pre>"); //NON-NLS return Bundle.IndexedText_warningMessage_noTextAvailable();
cachedString = sb.toString(); }
cachedChunk = chunkId; } else if (indexedText.isEmpty()) {
} catch (NoOpenCoreException ex) { return Bundle.IndexedText_warningMessage_noTextAvailable();
logger.log(Level.SEVERE, "No open core", ex); //NON-NLS
return "";
} }
cachedString = EscapeUtil.escapeHtml(indexedText).trim();
StringBuilder sb = new StringBuilder(cachedString.length() + 20);
sb.append("<pre>").append(cachedString).append("</pre>"); //NON-NLS
cachedString = sb.toString();
cachedChunk = chunkId;
return cachedString; return cachedString;
} }
private String getArtifactText() throws SolrServerException{ /**
try { * Get extracted artifact for a node from Solr
String indexedText = KeywordSearch.getServer().getSolrContent(this.objectId, 1); *
if (indexedText == null) indexedText = ""; * @return the extracted text
indexedText = EscapeUtil.escapeHtml(indexedText).trim(); *
StringBuilder sb = new StringBuilder(indexedText.length() + 20); * @throws NoOpenCoreException If no Solr core is available.
sb.append("<pre>").append(indexedText).append("</pre>"); //NON-NLS * @throws SolrServerException If there's a Solr communication or parsing
return sb.toString(); * issue.
} catch (NoOpenCoreException ex) { */
logger.log(Level.SEVERE, "No open core", ex); //NON-NLS private String getArtifactText() throws NoOpenCoreException, SolrServerException {
return ""; String indexedText = KeywordSearch.getServer().getSolrContent(this.objectId, 1);
if (indexedText == null || indexedText.isEmpty()) {
return Bundle.IndexedText_errorMessage_errorGettingText();
} }
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
StringBuilder sb = new StringBuilder(indexedText.length() + 20);
sb.append("<pre>").append(indexedText).append("</pre>"); //NON-NLS
return sb.toString();
} }
} }

View File

@ -33,6 +33,9 @@
<condition property="os.family" value="windows"> <condition property="os.family" value="windows">
<os family="windows"/> <os family="windows"/>
</condition> </condition>
<condition property="os.family" value="mac">
<os family="mac"/>
</condition>
<import file="build-${os.family}.xml"/> <import file="build-${os.family}.xml"/>
<!-- Third party tools dependencies --> <!-- Third party tools dependencies -->
@ -82,7 +85,13 @@
<copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/> <copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/>
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/> <copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
<copy file="${basedir}/KNOWN_ISSUES.txt" tofile="${zip-tmp}/${app.name}/KNOWN_ISSUES.txt"/> <copy file="${basedir}/KNOWN_ISSUES.txt" tofile="${zip-tmp}/${app.name}/KNOWN_ISSUES.txt"/>
<unzip src="${thirdparty.dir}/gstreamer/${os.family}/i386/0.10.7/gstreamer.zip" dest="${zip-tmp}/${app.name}/gstreamer"/> <if>
<equals arg1="${os.family}" arg2="windows"/>
<then>
<unzip src="${thirdparty.dir}/gstreamer/${os.family}/i386/0.10.7/gstreamer.zip" dest="${zip-tmp}/${app.name}/gstreamer"/>
</then>
</if>
<copy file="${basedir}/icons/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/> <copy file="${basedir}/icons/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
<!-- Copy the Autopsy documentation to the docs folder --> <!-- Copy the Autopsy documentation to the docs folder -->
@ -91,8 +100,17 @@
</copy> </copy>
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" /> <property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
<var name="jvm-value" value="--branding ${app.name} -J-Xms24m -J-Xmx4G -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication"/>
<!-- for Japanese localized version add option: -Duser.language=ja --> <!-- for Japanese localized version add option: -Duser.language=ja -->
<property name="jvm.options" value="&quot;--branding ${app.name} -J-Xms24m -J-Xmx4G -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication -J-Xdock:name=${app.title}&quot;" /> <if>
<equals arg1="${os.family}" arg2="mac"/>
<then>
<property name="jvm.options" value="&quot;${jvm-value} -J-Xdock:name=${app.title}&quot;"/>
</then>
<else>
<property name="jvm.options" value="&quot;${jvm-value}&quot;"/>
</else>
</if>
<propertyfile file="${app.property.file}"> <propertyfile file="${app.property.file}">
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties --> <!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
<entry key="default_options" value="@JVM_OPTIONS" /> <entry key="default_options" value="@JVM_OPTIONS" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,33 @@
/*! \page live_triage_page Live Triage
\section live_triage_overview Overview
The Live Triage feature allows you to load Autopsy onto a removable drive to run on target systems while making minimal changes to that target system. This will currently only work on Windows systems.
\section live_triage_create_drive Creating a live triage drive
To create a live triage drive, go to Tools->Make Live Triage Drive to bring up the main dialog.
\image html live_triage_dialog.png
Select the drive you want to use - any type of USB storage device will work. For best results use the fastest drive available. Once the process is complete the root folder will contain an Autopsy folder and a RunFromUSB.bat file.
\section live_triage_usage Running Autopsy from the live triage drive
Insert the drive into the target machine and browse to it in Windows Explorer. Right click on RunFromUSB.bat and select "Run as administrator". This is necessary to analyze the local drives.
\image html live_triage_script.png
Running the script will generate a few more directories on the USB drive. The configData directory stores all the data used by Autopsy - primarily configuration files and temporary files. You can make changes to the Autopsy settings and they will persist between runs. The cases directory is created as a recommended place to save your case data. You will need to browse to it when creating a case in Autopsy.
Once Autopsy is running, proceed to create a case as normal, making sure to save it on the USB drive.
\image html live_triage_case.png
Then choose the Local Disk data source and select the desired drive.
\image html live_triage_ds.png
See the \ref ds_local page for more information on local disk data sources.
*/

View File

@ -60,6 +60,7 @@ The following topics are available here:
- \subpage windows_authentication - \subpage windows_authentication
- \subpage multiuser_sec_page - \subpage multiuser_sec_page
- \subpage multiuser_page - \subpage multiuser_page
- \subpage live_triage_page
- \subpage advanced_page - \subpage advanced_page
If the topic you need is not listed, refer to the <a href="http://wiki.sleuthkit.org/index.php?title=Autopsy_User%27s_Guide">Autopsy Wiki</a> or join the <a href="https://lists.sourceforge.net/lists/listinfo/sleuthkit-users">SleuthKit User List</a> at SourceForge. If the topic you need is not listed, refer to the <a href="http://wiki.sleuthkit.org/index.php?title=Autopsy_User%27s_Guide">Autopsy Wiki</a> or join the <a href="https://lists.sourceforge.net/lists/listinfo/sleuthkit-users">SleuthKit User List</a> at SourceForge.

View File

@ -6,33 +6,275 @@
<description> <description>
Ruleset used by Autopsy Ruleset used by Autopsy
</description> </description>
<rule ref="rulesets/java/basic.xml/SimplifiedTernary"/>
<rule ref="rulesets/java/basic.xml"/> <rule ref="rulesets/java/basic.xml/AvoidUsingOctalValues"/>
<rule ref="rulesets/java/clone.xml"/> <rule ref="rulesets/java/basic.xml/BigIntegerInstantiation"/>
<rule ref="rulesets/java/codesize.xml"/> <rule ref="rulesets/java/basic.xml/ClassCastExceptionWithToArray"/>
<rule ref="rulesets/java/comments.xml"/> <rule ref="rulesets/java/basic.xml/ForLoopShouldBeWhileLoop"/>
<rule ref="rulesets/java/controversial.xml"/> <rule ref="rulesets/java/basic.xml/CheckResultSet"/>
<rule ref="rulesets/java/coupling.xml"/> <rule ref="rulesets/java/basic.xml/UnconditionalIfStatement"/>
<rule ref="rulesets/java/design.xml"/> <rule ref="rulesets/java/basic.xml/CheckSkipResult"/>
<rule ref="rulesets/java/empty.xml"/> <rule ref="rulesets/java/basic.xml/DontUseFloatTypeForLoopIndices"/>
<rule ref="rulesets/java/finalizers.xml"/> <rule ref="rulesets/java/basic.xml/MisplacedNullCheck"/>
<rule ref="rulesets/java/imports.xml"/> <rule ref="rulesets/java/basic.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>
<rule ref="rulesets/java/javabeans.xml"/> <rule ref="rulesets/java/basic.xml/BooleanInstantiation"/>
<rule ref="rulesets/java/logging-java.xml"/> <rule ref="rulesets/java/basic.xml/ExtendsObject"/>
<rule ref="rulesets/java/migrating.xml"/> <rule ref="rulesets/java/basic.xml/AvoidBranchingStatementAsLastInLoop"/>
<rule ref="rulesets/java/migrating_to_13.xml"/> <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking"/>
<rule ref="rulesets/java/migrating_to_14.xml"/> <rule ref="rulesets/java/basic.xml/ReturnFromFinallyBlock"/>
<rule ref="rulesets/java/migrating_to_15.xml"/> <rule ref="rulesets/java/basic.xml/AvoidThreadGroup"/>
<rule ref="rulesets/java/naming.xml"> <rule ref="rulesets/java/basic.xml/CollapsibleIfStatements"/>
<exclude name="MethodNamingConventions"/> <rule ref="rulesets/java/basic.xml/AvoidUsingHardCodedIP"/>
<rule ref="rulesets/java/basic.xml/CheckResultSet"/>
<rule ref="rulesets/java/basic.xml/DontCallThreadRun"/>
<rule ref="rulesets/java/basic.xml/BrokenNullCheck"/>
<rule ref="rulesets/java/basic.xml/AvoidMultipleUnaryOperators"/>
<rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode"/>
<rule ref="rulesets/java/basic.xml/JumbledIncrementer"/>
<rule ref="rulesets/java/braces.xml/WhileLoopsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/IfStmtsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/IfElseStmtsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/ForLoopsMustUseBraces"/>
<rule ref="rulesets/java/clone.xml/ProperCloneImplementation"/>
<rule ref="rulesets/java/clone.xml/CloneThrowsCloneNotSupportedException"/>
<rule ref="rulesets/java/clone.xml/CloneMethodMustImplementCloneable"/>
<rule ref="rulesets/java/clone.xml/CloneMethodReturnTypeMustMatchClassName"/>
<rule ref="rulesets/java/clone.xml/CloneMethodMustBePublic"/>
<rule ref="rulesets/java/codesize.xml/NPathComplexity"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveMethodLength"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveParameterList"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveClassLength"/>
<rule ref="rulesets/java/codesize.xml/CyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/StdCyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/ModifiedCyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/ExcessivePublicCount"/>
<rule ref="rulesets/java/codesize.xml/TooManyFields"/>
<rule ref="rulesets/java/codesize.xml/NcssMethodCount"/>
<rule ref="rulesets/java/codesize.xml/NcssTypeCount"/>
<rule ref="rulesets/java/codesize.xml/NcssConstructorCount"/>
<rule ref="rulesets/java/codesize.xml/TooManyMethods"/>
<rule ref="rulesets/java/comments.xml/CommentRequired">
<properties>
<!-- Disabled because we have lots of undocumented fields -->
<property name="fieldCommentRequirement" value="Unwanted"/>
</properties>
</rule> </rule>
<rule ref="rulesets/java/optimizations.xml"/> <!-- Commented out because it was flagged some of our header / copyright comments
<rule ref="rulesets/java/strictexception.xml"> <rule ref="rulesets/java/comments.xml/CommentSize"/> -->
<exclude name="AvoidCatchingGenericException"/> <rule ref="rulesets/java/comments.xml/CommentContent"/>
<rule ref="rulesets/java/strings.xml"/> <rule ref="rulesets/java/comments.xml/CommentDefaultAccessModifier"/>
<rule ref="rulesets/java/sunsecure.xml"/> <!--
<rule ref="rulesets/java/typeresolution.xml"/> Commented out because they are controversial and we want basics right now.
<rule ref="rulesets/java/unnecessary.xml"/> <rule ref="rulesets/java/controversial.xml/NullAssignment"/>
<rule ref="rulesets/java/unusedcode.xml"/> <rule ref="rulesets/java/controversial.xml/OnlyOneReturn"/>
<rule ref="rulesets/java/controversial.xml/AssignmentInOperand"/>
<rule ref="rulesets/java/controversial.xml/AtLeastOneConstructor"/>
<rule ref="rulesets/java/controversial.xml/DontImportSun"/>
<rule ref="rulesets/java/controversial.xml/SuspiciousOctalEscape"/>
<rule ref="rulesets/java/controversial.xml/CallSuperInConstructor"/>
<rule ref="rulesets/java/controversial.xml/UnnecessaryParentheses"/>
<rule ref="rulesets/java/controversial.xml/DataflowAnomalyAnalysis"/>
<rule ref="rulesets/java/controversial.xml/AvoidFinalLocalVariable"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingShortType"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingVolatile"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode"/>
<rule ref="rulesets/java/controversial.xml/AvoidAccessibilityAlteration"/>
<rule ref="rulesets/java/controversial.xml/DoNotCallGarbageCollectionExplicitly"/>
<rule ref="rulesets/java/controversial.xml/AvoidPrefixingMethodParameters"/>
<rule ref="rulesets/java/controversial.xml/AvoidLiteralsInIfCondition"/>
<rule ref="rulesets/java/controversial.xml/UseObjectForClearerAPI"/>
<rule ref="rulesets/java/controversial.xml/UseConcurrentHashMap"/>
<rule ref="rulesets/java/controversial.xml/OneDeclarationPerLine"/>
<rule ref="rulesets/java/controversial.xml/DefaultPackage"/>
<rule ref="rulesets/java/controversial.xml/UnnecessaryConstructor"/>
-->
<rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects"/>
<rule ref="rulesets/java/coupling.xml/ExcessiveImports"/>
<rule ref="rulesets/java/coupling.xml/LooseCoupling"/>
<rule ref="rulesets/java/coupling.xml/LoosePackageCoupling"/>
<!-- Commented out because we have not enforced this in the past
<rule ref="rulesets/java/coupling.xml/LawOfDemeter"/> -->
<rule ref="rulesets/java/design.xml/UseUtilityClass"/>
<rule ref="rulesets/java/design.xml/AvoidDeeplyNestedIfStmts"/>
<rule ref="rulesets/java/design.xml/SwitchDensity"/>
<rule ref="rulesets/java/design.xml/ConstructorCallsOverridableMethod"/>
<rule ref="rulesets/java/design.xml/AccessorClassGeneration"/>
<rule ref="rulesets/java/design.xml/FinalFieldCouldBeStatic"/>
<rule ref="rulesets/java/design.xml/CloseResource"/>
<rule ref="rulesets/java/design.xml/NonStaticInitializer"/>
<rule ref="rulesets/java/design.xml/DefaultLabelNotLastInSwitchStmt"/>
<rule ref="rulesets/java/design.xml/OptimizableToArrayCall"/>
<rule ref="rulesets/java/design.xml/BadComparison"/>
<rule ref="rulesets/java/design.xml/ConfusingTernary"/>
<rule ref="rulesets/java/design.xml/InstantiationToGetClass"/>
<rule ref="rulesets/java/design.xml/IdempotentOperations"/>
<rule ref="rulesets/java/design.xml/SimpleDateFormatNeedsLocale"/>
<rule ref="rulesets/java/design.xml/ImmutableField"/>
<rule ref="rulesets/java/design.xml/UseLocaleWithCaseConversions"/>
<rule ref="rulesets/java/design.xml/AvoidProtectedFieldInFinalClass"/>
<rule ref="rulesets/java/design.xml/AvoidSynchronizedAtMethodLevel"/>
<rule ref="rulesets/java/design.xml/UseNotifyAllInsteadOfNotify"/>
<rule ref="rulesets/java/design.xml/AbstractClassWithoutAbstractMethod"/>
<rule ref="rulesets/java/design.xml/SimplifyConditional"/>
<rule ref="rulesets/java/design.xml/PositionLiteralsFirstInCaseInsensitiveComparisons"/>
<rule ref="rulesets/java/design.xml/UnnecessaryLocalBeforeReturn"/>
<rule ref="rulesets/java/design.xml/NonThreadSafeSingleton"/>
<rule ref="rulesets/java/design.xml/SingleMethodSingleton"/>
<rule ref="rulesets/java/design.xml/SingletonClassReturningNewInstance"/>
<rule ref="rulesets/java/design.xml/UncommentedEmptyConstructor"/>
<rule ref="rulesets/java/design.xml/AvoidConstantsInterface"/>
<rule ref="rulesets/java/design.xml/UnsynchronizedStaticDateFormatter"/>
<rule ref="rulesets/java/design.xml/PreserveStackTrace"/>
<rule ref="rulesets/java/design.xml/UseCollectionIsEmpty"/>
<rule ref="rulesets/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
<rule ref="rulesets/java/design.xml/EmptyMethodInAbstractClassShouldBeAbstract"/>
<rule ref="rulesets/java/design.xml/ReturnEmptyArrayRatherThanNull"/>
<rule ref="rulesets/java/design.xml/AbstractClassWithoutAnyMethod"/>
<rule ref="rulesets/java/design.xml/TooFewBranchesForASwitchStatement"/>
<rule ref="rulesets/java/design.xml/UseVarargs"/>
<!-- Commented out because it flagged many of the NetBeans created UI classes that place
fields at various places in the class
<rule ref="rulesets/java/design.xml/FieldDeclarationsShouldBeAtStartOfClass"/> -->
<rule ref="rulesets/java/design.xml/GodClass"/>
<rule ref="rulesets/java/design.xml/AvoidProtectedMethodInFinalClassNotExtending"/>
<rule ref="rulesets/java/design.xml/ConstantsInInterface"/>
<rule ref="rulesets/java/design.xml/CompareObjectsWithEquals"/>
<rule ref="rulesets/java/design.xml/LogicInversion"/>
<rule ref="rulesets/java/design.xml/SingularField"/>
<rule ref="rulesets/java/design.xml/SimplifyBooleanReturns"/>
<rule ref="rulesets/java/design.xml/AvoidInstanceofChecksInCatchClause"/>
<rule ref="rulesets/java/design.xml/NonCaseLabelInSwitchStatement"/>
<rule ref="rulesets/java/design.xml/NonStaticInitializer"/>
<rule ref="rulesets/java/design.xml/AvoidReassigningParameters"/>
<rule ref="rulesets/java/design.xml/SwitchStmtsShouldHaveDefault"/>
<rule ref="rulesets/java/design.xml/MissingBreakInSwitch"/>
<rule ref="rulesets/java/design.xml/EqualsNull"/>
<rule ref="rulesets/java/design.xml/UncommentedEmptyMethodBody"/>
<rule ref="rulesets/java/design.xml/SimplifyBooleanExpressions"/>
<rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic"/>
<rule ref="rulesets/java/design.xml/MissingStaticMethodInNonInstantiatableClass"/>
<rule ref="rulesets/java/design.xml/PositionLiteralsFirstInComparisons"/>
<rule ref="rulesets/java/empty.xml/EmptyCatchBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyWhileStmt"/>
<rule ref="rulesets/java/empty.xml/EmptyFinallyBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyIfStmt"/>
<rule ref="rulesets/java/empty.xml/EmptyStatementNotInLoop"/>
<rule ref="rulesets/java/empty.xml/EmptyTryBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyStatementBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyStaticInitializer"/>
<rule ref="rulesets/java/empty.xml/EmptyInitializer"/>
<rule ref="rulesets/java/empty.xml/EmptySwitchStatements"/>
<rule ref="rulesets/java/empty.xml/EmptySynchronizedBlock"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeOverloaded"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeShouldBeProtected"/>
<rule ref="rulesets/java/finalizers.xml/AvoidCallingFinalize"/>
<rule ref="rulesets/java/finalizers.xml/EmptyFinalizer"/>
<rule ref="rulesets/java/imports.xml/TooManyStaticImports"/>
<rule ref="rulesets/java/imports.xml/UnusedImports"/>
<rule ref="rulesets/java/imports.xml/ImportFromSamePackage"/>
<rule ref="rulesets/java/imports.xml/DuplicateImports"/>
<rule ref="rulesets/java/imports.xml/DontImportJavaLang"/>
<rule ref="rulesets/java/imports.xml/UnnecessaryFullyQualifiedName"/>
<!-- Disabled because it generated a lot of errors for non-Beans
<rule ref="rulesets/java/javabeans.xml/BeanMembersShouldSerialize"/>-->
<rule ref="rulesets/java/javabeans.xml/MissingSerialVersionUID"/>
<rule ref="rulesets/java/logging-java.xml/MoreThanOneLogger"/>
<rule ref="rulesets/java/logging-java.xml/LoggerIsNotStaticFinal"/>
<rule ref="rulesets/java/logging-java.xml/SystemPrintln"/>
<rule ref="rulesets/java/logging-java.xml/AvoidPrintStackTrace"/>
<rule ref="rulesets/java/logging-java.xml/GuardLogStatementJavaUtil"/>
<rule ref="rulesets/java/logging-java.xml/InvalidSlf4jMessageFormat"/>
<rule ref="rulesets/java/migrating.xml/ReplaceVectorWithList"/>
<rule ref="rulesets/java/migrating.xml/ReplaceHashtableWithMap"/>
<rule ref="rulesets/java/migrating.xml/ReplaceEnumerationWithIterator"/>
<rule ref="rulesets/java/migrating.xml/AvoidEnumAsIdentifier"/>
<rule ref="rulesets/java/migrating.xml/AvoidAssertAsIdentifier"/>
<rule ref="rulesets/java/migrating.xml/IntegerInstantiation"/>
<rule ref="rulesets/java/migrating.xml/ByteInstantiation"/>
<rule ref="rulesets/java/migrating.xml/ShortInstantiation"/>
<rule ref="rulesets/java/migrating.xml/LongInstantiation"/>
<!-- Disabled because it wanted all private static to be caps
<rule ref="rulesets/java/naming.xml/VariableNamingConventions"/> -->
<rule ref="rulesets/java/naming.xml/AvoidDollarSigns"/>
<rule ref="rulesets/java/naming.xml/AbstractNaming"/>
<rule ref="rulesets/java/naming.xml/SuspiciousHashcodeMethodName"/>
<rule ref="rulesets/java/naming.xml/SuspiciousConstantFieldName"/>
<rule ref="rulesets/java/naming.xml/SuspiciousEqualsMethodName"/>
<rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName"/>
<rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName"/>
<rule ref="rulesets/java/naming.xml/MisleadingVariableName"/>
<rule ref="rulesets/java/naming.xml/ShortClassName"/>
<rule ref="rulesets/java/naming.xml/ClassNamingConventions"/>
<rule ref="rulesets/java/naming.xml/MethodNamingConventions"/>
<rule ref="rulesets/java/naming.xml/GenericsNaming"/>
<rule ref="rulesets/java/naming.xml/NoPackage"/>
<rule ref="rulesets/java/naming.xml/MethodWithSameNameAsEnclosingClass"/>
<rule ref="rulesets/java/naming.xml/ShortVariable"/>
<rule ref="rulesets/java/naming.xml/LongVariable"/>
<rule ref="rulesets/java/naming.xml/ShortMethodName"/>
<rule ref="rulesets/java/naming.xml/BooleanGetMethodName"/>
<rule ref="rulesets/java/naming.xml/PackageCase"/>
<rule ref="rulesets/java/optimizations.xml/LocalVariableCouldBeFinal"/>
<rule ref="rulesets/java/optimizations.xml/MethodArgumentCouldBeFinal"/>
<rule ref="rulesets/java/optimizations.xml/AvoidInstantiatingObjectsInLoops"/>
<rule ref="rulesets/java/optimizations.xml/UseArrayListInsteadOfVector"/>
<rule ref="rulesets/java/optimizations.xml/SimplifyStartsWith"/>
<rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends"/>
<rule ref="rulesets/java/optimizations.xml/UseArraysAsList"/>
<rule ref="rulesets/java/optimizations.xml/AvoidArrayLoops"/>
<rule ref="rulesets/java/optimizations.xml/UnnecessaryWrapperObjectCreation"/>
<rule ref="rulesets/java/optimizations.xml/AddEmptyString"/>
<rule ref="rulesets/java/optimizations.xml/RedundantFieldInitializer"/>
<rule ref="rulesets/java/optimizations.xml/PrematureDeclaration"/>
<rule ref="rulesets/java/strictexception.xml/SignatureDeclareThrowsException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingThrowable"/>
<rule ref="rulesets/java/strictexception.xml/ExceptionAsFlowControl"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingNPE"/>
<rule ref="rulesets/java/strictexception.xml/AvoidRethrowingException"/>
<rule ref="rulesets/java/strictexception.xml/DoNotExtendJavaLangError"/>
<rule ref="rulesets/java/strictexception.xml/DoNotThrowExceptionInFinally"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingNewInstanceOfSameException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidLosingExceptionInformation"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingRawExceptionTypes"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingNullPointerException"/>
<rule ref="rulesets/java/strings.xml/AvoidDuplicateLiterals"/>
<rule ref="rulesets/java/strings.xml/InefficientStringBuffering"/>
<rule ref="rulesets/java/strings.xml/AppendCharacterWithChar"/>
<rule ref="rulesets/java/strings.xml/ConsecutiveAppendsShouldReuse"/>
<rule ref="rulesets/java/strings.xml/ConsecutiveLiteralAppends"/>
<rule ref="rulesets/java/strings.xml/UseIndexOfChar"/>
<rule ref="rulesets/java/strings.xml/InefficientEmptyStringCheck"/>
<rule ref="rulesets/java/strings.xml/InsufficientStringBufferDeclaration"/>
<rule ref="rulesets/java/strings.xml/UselessStringValueOf"/>
<rule ref="rulesets/java/strings.xml/StringBufferInstantiationWithChar"/>
<rule ref="rulesets/java/strings.xml/AvoidStringBufferField"/>
<rule ref="rulesets/java/strings.xml/StringInstantiation"/>
<rule ref="rulesets/java/strings.xml/UseEqualsToCompareStrings"/>
<rule ref="rulesets/java/strings.xml/StringToString"/>
<rule ref="rulesets/java/strings.xml/UseStringBufferLength"/>
<rule ref="rulesets/java/strings.xml/UnnecessaryCaseChange"/>
<rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray"/>
<rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly"/>
<rule ref="rulesets/java/typeresolution.xml/LooseCoupling"/>
<rule ref="rulesets/java/typeresolution.xml/CloneMethodMustImplementCloneable"/>
<rule ref="rulesets/java/typeresolution.xml/UnusedImports"/>
<rule ref="rulesets/java/typeresolution.xml/SignatureDeclareThrowsException"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryConversionTemporary"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryFinalModifier"/>
<rule ref="rulesets/java/unnecessary.xml/UselessOverridingMethod"/>
<rule ref="rulesets/java/unnecessary.xml/UnusedNullCheckInEquals"/>
<rule ref="rulesets/java/unnecessary.xml/UselessParentheses"/>
<rule ref="rulesets/java/unnecessary.xml/UselessQualifiedThis"/>
<rule ref="rulesets/java/unnecessary.xml/UselessOperationOnImmutable"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryReturn"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedModifier"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable"/>
<!-- Commented out because it flagged many event listeners and other interfaces.
<rule ref="rulesets/java/unusedcode.xml/UnusedFormalParameter"/> -->
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateMethod"/>
</ruleset> </ruleset>

View File

@ -810,7 +810,7 @@ class TestConfiguration(object):
if parsed_config.getElementsByTagName("singleUser_golddir"): if parsed_config.getElementsByTagName("singleUser_golddir"):
self.singleUser_gold = parsed_config.getElementsByTagName("singleUser_golddir")[0].getAttribute("value").encode().decode("utf_8") self.singleUser_gold = parsed_config.getElementsByTagName("singleUser_golddir")[0].getAttribute("value").encode().decode("utf_8")
if parsed_config.getElementsByTagName("timing"): if parsed_config.getElementsByTagName("timing"):
self.timing = parsed_config.getElementsByTagName("timing")[0].getAttribute("value").encode().decode("utf_8") self.timing = ("True" == parsed_config.getElementsByTagName("timing")[0].getAttribute("value").encode().decode("utf_8"))
if parsed_config.getElementsByTagName("autopsyPlatform"): if parsed_config.getElementsByTagName("autopsyPlatform"):
self.autopsyPlatform = parsed_config.getElementsByTagName("autopsyPlatform")[0].getAttribute("value").encode().decode("utf_8") self.autopsyPlatform = parsed_config.getElementsByTagName("autopsyPlatform")[0].getAttribute("value").encode().decode("utf_8")
# Multi-user settings # Multi-user settings
@ -1392,7 +1392,7 @@ class Logs(object):
try: try:
Logs._fill_ingest_data(test_data) Logs._fill_ingest_data(test_data)
except Exception as e: except Exception as e:
Errors.print_error("Error: Unknown fatal error when filling test_config data.") Errors.print_error("Error when filling test_config data.")
Errors.print_error(str(e) + "\n") Errors.print_error(str(e) + "\n")
logging.critical(traceback.format_exc()) logging.critical(traceback.format_exc())
# If running in verbose mode (-v) # If running in verbose mode (-v)
@ -1454,10 +1454,10 @@ class Logs(object):
Errors.print_error("Error: Unable to open autopsy.log.0.") Errors.print_error("Error: Unable to open autopsy.log.0.")
Errors.print_error(str(e) + "\n") Errors.print_error(str(e) + "\n")
logging.warning(traceback.format_exc()) logging.warning(traceback.format_exc())
# Start date must look like: "Fri Mar 27 13:27:34 EDT 2015" # Start date must look like: ""
# End date must look like: "Mon Jul 16 13:02:42 2012" # End date must look like: "Mon Jul 16 13:02:42 2012"
# *** If logging time format ever changes this will break *** # *** If logging time format ever changes this will break ***
start = datetime.datetime.strptime(test_data.start_date, "%a %b %d %H:%M:%S %Z %Y") start = datetime.datetime.strptime(test_data.start_date, "%Y-%m-%d %H:%M:%S.%f")
end = datetime.datetime.strptime(test_data.end_date, "%a %b %d %H:%M:%S %Y") end = datetime.datetime.strptime(test_data.end_date, "%a %b %d %H:%M:%S %Y")
test_data.total_test_time = str(end - start) test_data.total_test_time = str(end - start)
@ -1469,7 +1469,6 @@ class Logs(object):
test_data.heap_space = search_logs("Heap memory usage:", test_data)[0].rstrip().split(": ")[1] test_data.heap_space = search_logs("Heap memory usage:", test_data)[0].rstrip().split(": ")[1]
ingest_line = search_logs("Ingest (including enqueue)", test_data)[0] ingest_line = search_logs("Ingest (including enqueue)", test_data)[0]
test_data.total_ingest_time = get_word_at(ingest_line, 6).rstrip() test_data.total_ingest_time = get_word_at(ingest_line, 6).rstrip()
message_line_count = find_msg_in_log_set("Ingest messages count:", test_data) message_line_count = find_msg_in_log_set("Ingest messages count:", test_data)
test_data.indexed_files = message_line_count test_data.indexed_files = message_line_count