mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 1903-IngestSetFilter
This commit is contained in:
commit
574200ff3b
@ -15,6 +15,10 @@ file.reference.StixLib.jar=release/modules/ext/StixLib.jar
|
||||
file.reference.tika-core-1.5.jar=release/modules/ext/tika-core-1.5.jar
|
||||
file.reference.Tsk_DataModel_PostgreSQL.jar=release/modules/ext/Tsk_DataModel_PostgreSQL.jar
|
||||
file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
|
||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
||||
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1-src.zip
|
||||
@ -23,5 +27,6 @@ nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
source.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1-src.zip!/Source/
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
spec.version.base=10.7
|
||||
|
||||
|
@ -231,6 +231,7 @@
|
||||
<package>org.sleuthkit.autopsy.casemodule.events</package>
|
||||
<package>org.sleuthkit.autopsy.casemodule.services</package>
|
||||
<package>org.sleuthkit.autopsy.contentviewers</package>
|
||||
<package>org.sleuthkit.autopsy.coordinationservice</package>
|
||||
<package>org.sleuthkit.autopsy.core</package>
|
||||
<package>org.sleuthkit.autopsy.core.events</package>
|
||||
<package>org.sleuthkit.autopsy.corecomponentinterfaces</package>
|
||||
@ -326,6 +327,22 @@
|
||||
<runtime-relative-path>ext/Tsk_DataModel_PostgreSQL.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/Tsk_DataModel_PostgreSQL.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/zookeeper-3.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/zookeeper-3.4.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-client-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-client-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-recipes-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-recipes-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-framework-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
@ -133,6 +133,7 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type
|
||||
Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted.
|
||||
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
|
||||
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
|
||||
Case.exception.errorLocking=Unable to open case being updated by another user.
|
||||
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\
|
||||
Case Name\: {0}\n\
|
||||
Case Directory\: {1}
|
||||
|
@ -39,6 +39,12 @@ import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle;
|
||||
@ -55,6 +61,8 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||
@ -280,6 +288,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
private static final AutopsyEventPublisher eventPublisher = new AutopsyEventPublisher();
|
||||
private static String appName;
|
||||
private static Case currentCase;
|
||||
private static CoordinationService.Lock currentCaseLock;
|
||||
private static ExecutorService currentCaseExecutor;
|
||||
private final CaseMetadata caseMetadata;
|
||||
private final SleuthkitCase db;
|
||||
private final Services services;
|
||||
@ -832,7 +842,27 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* exception.
|
||||
*/
|
||||
public void closeCase() throws CaseActionException {
|
||||
|
||||
// The unlock must happen on the same thread that created the lock
|
||||
Future<Void> future = getCurrentCaseExecutor().submit(() -> {
|
||||
try{
|
||||
if (currentCaseLock != null) {
|
||||
currentCaseLock.release();
|
||||
currentCaseLock = null;
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error releasing shared lock"), exx);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
try{
|
||||
future.get();
|
||||
} catch (InterruptedException | ExecutionException ex){
|
||||
logger.log(Level.SEVERE, String.format("Interrupted while releasing shared lock"), ex);
|
||||
}
|
||||
|
||||
changeCurrentCase(null);
|
||||
|
||||
try {
|
||||
services.close();
|
||||
this.db.close();
|
||||
@ -940,6 +970,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
public static void create(String caseDir, String caseName, String caseNumber, String examiner, CaseType caseType) throws CaseActionException {
|
||||
logger.log(Level.INFO, "Attempting to create case {0} in directory = {1}", new Object[]{caseName, caseDir}); //NON-NLS
|
||||
|
||||
CoordinationService.Lock exclusiveResourceLock = null;
|
||||
boolean caseCreatedSuccessfully = false;
|
||||
|
||||
/*
|
||||
* Create case directory if it doesn't already exist.
|
||||
*/
|
||||
@ -963,6 +996,39 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
dbName = indexName;
|
||||
}
|
||||
|
||||
try{
|
||||
/* If this is a multi-user case, acquire two locks:
|
||||
* - a shared lock on the case to prevent it from being deleted while open
|
||||
* - an exclusive lock to prevent multiple clients from executing openCase simultaneously
|
||||
*/
|
||||
if(caseType == CaseType.MULTI_USER_CASE){
|
||||
try{
|
||||
|
||||
// The shared lock uses case directory
|
||||
// The shared lock needs to be created on a special thread so it can be released
|
||||
// from the same thread.
|
||||
Future<Void> future = getCurrentCaseExecutor().submit(() -> {
|
||||
currentCaseLock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetSharedLock(CoordinationService.CategoryNode.CASES, caseDir);
|
||||
if (null == currentCaseLock) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
future.get();
|
||||
|
||||
// The exclusive lock uses the unique case name.
|
||||
// This lock does not need to be on a special thread since it will be released before
|
||||
// leaving this method
|
||||
exclusiveResourceLock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.RESOURCE,
|
||||
dbName, 12, TimeUnit.HOURS);
|
||||
if (null == exclusiveResourceLock) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
} catch (Exception ex){
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the case metadata (.aut) file.
|
||||
*/
|
||||
@ -1003,8 +1069,39 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
|
||||
Case newCase = new Case(metadata, db);
|
||||
changeCurrentCase(newCase);
|
||||
caseCreatedSuccessfully = true;
|
||||
|
||||
logger.log(Level.INFO, "Created case {0} in directory = {1}", new Object[]{caseName, caseDir}); //NON-NLS
|
||||
} finally {
|
||||
// Release the exclusive resource lock
|
||||
try {
|
||||
if (exclusiveResourceLock != null) {
|
||||
exclusiveResourceLock.release();
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error releasing resource lock for case {0}", caseName), exx);
|
||||
}
|
||||
|
||||
// If an error occurred while opening the case, release the shared case lock as well
|
||||
if(! caseCreatedSuccessfully){
|
||||
Future<Void> future = getCurrentCaseExecutor().submit(() -> {
|
||||
try {
|
||||
if (currentCaseLock != null) {
|
||||
currentCaseLock.release();
|
||||
currentCaseLock = null;
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error releasing shared lock for case {0}", caseName), exx);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
try{
|
||||
future.get();
|
||||
} catch (InterruptedException | ExecutionException ex){
|
||||
logger.log(Level.SEVERE, String.format("Interrupted while releasing shared lock"), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1143,6 +1240,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
*/
|
||||
public static void open(String caseMetadataFilePath) throws CaseActionException {
|
||||
logger.log(Level.INFO, "Opening case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
|
||||
CoordinationService.Lock exclusiveResourceLock = null;
|
||||
boolean caseOpenedSuccessfully = false;
|
||||
|
||||
/*
|
||||
* Verify the extension of the case metadata file.
|
||||
@ -1158,6 +1257,39 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
CaseMetadata metadata = new CaseMetadata(Paths.get(caseMetadataFilePath));
|
||||
CaseType caseType = metadata.getCaseType();
|
||||
|
||||
/*
|
||||
* If this is a multi-user case, acquire two locks:
|
||||
* - a shared lock on the case to prevent it from being deleted while open
|
||||
* - an exclusive lock to prevent multiple clients from executing openCase simultaneously
|
||||
*/
|
||||
if(caseType == CaseType.MULTI_USER_CASE){
|
||||
try{
|
||||
|
||||
// The shared lock uses the case directory
|
||||
// The shared lock needs to be created on a special thread so it can be released
|
||||
// from the same thread.
|
||||
Future<Void> future = getCurrentCaseExecutor().submit(() -> {
|
||||
currentCaseLock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetSharedLock(CoordinationService.CategoryNode.CASES, metadata.getCaseDirectory());
|
||||
if (null == currentCaseLock) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
future.get();
|
||||
|
||||
// The exclusive lock uses the unique case name
|
||||
// This lock does not need to be on a special thread since it will be released before
|
||||
// leaving this method
|
||||
exclusiveResourceLock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.RESOURCE,
|
||||
metadata.getCaseDatabaseName(), 12, TimeUnit.HOURS);
|
||||
if (null == exclusiveResourceLock) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
} catch (Exception ex){
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.exception.errorLocking", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the case database.
|
||||
*/
|
||||
@ -1221,6 +1353,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
Case openedCase = new Case(metadata, db);
|
||||
changeCurrentCase(openedCase);
|
||||
caseOpenedSuccessfully = true;
|
||||
|
||||
} catch (CaseMetadataException ex) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.metaDataFileCorrupt.exception.msg"), ex); //NON-NLS
|
||||
@ -1233,6 +1366,36 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* user-friendly messages, so propagate the exception message.
|
||||
*/
|
||||
throw new CaseActionException(ex.getMessage(), ex);
|
||||
} finally {
|
||||
// Release the exclusive resource lock
|
||||
try {
|
||||
if (exclusiveResourceLock != null) {
|
||||
exclusiveResourceLock.release();
|
||||
exclusiveResourceLock = null;
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error releasing resource lock for case {0}", caseMetadataFilePath), exx);
|
||||
}
|
||||
|
||||
// If an error occurred while opening the case, release the shared case lock as well
|
||||
if(! caseOpenedSuccessfully){
|
||||
Future<Void> future = getCurrentCaseExecutor().submit(() -> {
|
||||
try {
|
||||
if (currentCaseLock != null) {
|
||||
currentCaseLock.release();
|
||||
currentCaseLock = null;
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error releasing shared lock for case {0}", caseMetadataFilePath), exx);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
try{
|
||||
future.get();
|
||||
} catch (InterruptedException | ExecutionException ex){
|
||||
logger.log(Level.SEVERE, String.format("Interrupted while releasing shared lock"), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1433,13 +1596,24 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
*
|
||||
* @param casePath A case directory path.
|
||||
*
|
||||
* @return True if the deleteion succeeded, false otherwise.
|
||||
* @return True if the deletion succeeded, false otherwise.
|
||||
*/
|
||||
static boolean deleteCaseDirectory(File casePath) {
|
||||
logger.log(Level.INFO, "Deleting case directory: {0}", casePath.getAbsolutePath()); //NON-NLS
|
||||
return FileUtil.deleteDir(casePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single thread executor for the current case, creating it if necessary.
|
||||
* @return The executor
|
||||
*/
|
||||
private static ExecutorService getCurrentCaseExecutor(){
|
||||
if(currentCaseExecutor == null){
|
||||
currentCaseExecutor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
return currentCaseExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time zone(s) of the image data source(s) in this case.
|
||||
*
|
||||
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.coordinationservice;
|
||||
package org.sleuthkit.autopsy.coordinationservice;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -50,7 +50,8 @@ public final class CoordinationService {
|
||||
|
||||
CASES("cases"),
|
||||
MANIFESTS("manifests"),
|
||||
CONFIG("config");
|
||||
CONFIG("config"),
|
||||
RESOURCE("resource");
|
||||
|
||||
private final String displayName;
|
||||
|
@ -16,15 +16,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
package org.sleuthkit.autopsy.coordinationservice;
|
||||
|
||||
/**
|
||||
* Namespace elements for auto ingest coordination service nodes.
|
||||
*/
|
||||
final class CoordinationServiceNamespace {
|
||||
public final class CoordinationServiceNamespace {
|
||||
private static final String ROOT = "autopsy";
|
||||
|
||||
static String getRoot() {
|
||||
public static String getRoot() {
|
||||
return ROOT;
|
||||
}
|
||||
|
@ -101,8 +101,6 @@ public class ImageNode extends AbstractContentNode<Image> {
|
||||
"ImageNode.getActions.openFileSearchByAttr.text=Open File Search by Attributes",})
|
||||
public Action[] getActions(boolean context) {
|
||||
|
||||
|
||||
|
||||
List<Action> actionsList = new ArrayList<Action>();
|
||||
for (Action a : super.getActions(true)) {
|
||||
actionsList.add(a);
|
||||
@ -216,6 +214,11 @@ public class ImageNode extends AbstractContentNode<Image> {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* This property change listener refreshes the tree when a new file is
|
||||
* carved out of this image (i.e, the image is being treated as raw bytes
|
||||
* and was ingested by the RawDSProcessor).
|
||||
*/
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
@ -256,5 +259,4 @@ public class ImageNode extends AbstractContentNode<Image> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
@ -80,6 +80,10 @@ public class VolumeNode extends AbstractContentNode<Volume> {
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
/*
|
||||
* This property change listener refreshes the tree when a new file is
|
||||
* carved out of the unallocated space of this volume.
|
||||
*/
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
|
@ -1,17 +1,12 @@
|
||||
file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar
|
||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
||||
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
||||
file.reference.jackson-core-2.7.0.jar=release/modules/ext/jackson-core-2.7.0.jar
|
||||
file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar
|
||||
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
||||
file.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1.jar
|
||||
file.reference.tika-core-1.5.jar=release/modules/ext/tika-core-1.5.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar
|
||||
javadoc.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1-javadoc.jar
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-sources.jar
|
||||
source.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1-sources.jar
|
||||
|
@ -119,14 +119,6 @@
|
||||
<package>org.sleuthkit.autopsy.experimental.autoingest</package>
|
||||
<package>org.sleuthkit.autopsy.experimental.configuration</package>
|
||||
</public-packages>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/zookeeper-3.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/zookeeper-3.4.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-client-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-client-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mchange-commons-java-0.2.9.jar</binary-origin>
|
||||
@ -139,10 +131,6 @@
|
||||
<runtime-relative-path>ext/tika-core-1.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/tika-core-1.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-recipes-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-recipes-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackson-core-2.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jackson-core-2.7.0.jar</binary-origin>
|
||||
@ -151,10 +139,6 @@
|
||||
<runtime-relative-path>ext/c3p0-0.9.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/c3p0-0.9.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-framework-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/solr-solrj-4.9.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/solr-solrj-4.9.1.jar</binary-origin>
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
@ -29,9 +30,9 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.List;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
@ -98,9 +99,9 @@ import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.openide.util.Lookup;
|
||||
|
@ -18,10 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
@ -37,8 +34,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseNewAction;
|
||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
|
||||
/**
|
||||
* Handles opening, locking, and unlocking cases in review mode. Instances of
|
||||
@ -47,7 +43,7 @@ import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationServic
|
||||
* dispatch thread (EDT). Because of the tight coupling to the UI, exception
|
||||
* messages are deliberately user-friendly.
|
||||
*/
|
||||
final class ReviewModeCaseManager implements PropertyChangeListener {
|
||||
final class ReviewModeCaseManager {
|
||||
|
||||
/*
|
||||
* Provides uniform exceptions with user-friendly error messages.
|
||||
@ -77,14 +73,7 @@ final class ReviewModeCaseManager implements PropertyChangeListener {
|
||||
*/
|
||||
synchronized static ReviewModeCaseManager getInstance() {
|
||||
if (instance == null) {
|
||||
/*
|
||||
* Two stage construction is used here to avoid allowing "this"
|
||||
* reference to escape from the constructor via registering as an
|
||||
* PropertyChangeListener. This is to ensure that a partially
|
||||
* constructed manager is not published to other threads.
|
||||
*/
|
||||
instance = new ReviewModeCaseManager();
|
||||
Case.addPropertyChangeListener(instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@ -149,17 +138,7 @@ final class ReviewModeCaseManager implements PropertyChangeListener {
|
||||
* requirement
|
||||
*/
|
||||
synchronized void openCaseInEDT(Path caseMetadataFilePath) throws ReviewModeCaseManagerException {
|
||||
Path caseFolderPath = caseMetadataFilePath.getParent();
|
||||
try {
|
||||
/*
|
||||
* Acquire a lock on the case folder. If the lock cannot be
|
||||
* acquired, the case cannot be opened.
|
||||
*/
|
||||
currentCaseLock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetSharedLock(CoordinationService.CategoryNode.CASES, caseFolderPath.toString());
|
||||
if (null == currentCaseLock) {
|
||||
throw new ReviewModeCaseManagerException("Could not get shared access to multi-user case folder");
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the case.
|
||||
*/
|
||||
@ -177,64 +156,8 @@ final class ReviewModeCaseManager implements PropertyChangeListener {
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
|
||||
});
|
||||
|
||||
} catch (CoordinationServiceException | ReviewModeCaseManagerException | CaseActionException ex) {
|
||||
/*
|
||||
* Release the coordination service lock on the case folder.
|
||||
*/
|
||||
try {
|
||||
if (currentCaseLock != null) {
|
||||
currentCaseLock.release();
|
||||
currentCaseLock = null;
|
||||
}
|
||||
} catch (CoordinationService.CoordinationServiceException exx) {
|
||||
logger.log(Level.SEVERE, String.format("Error deleting legacy LOCKED state file for case at %s", caseFolderPath), exx);
|
||||
}
|
||||
|
||||
if (ex instanceof CoordinationServiceException) {
|
||||
throw new ReviewModeCaseManagerException("Could not get access to the case folder from the coordination service, contact administrator", ex);
|
||||
} else if (ex instanceof IOException) {
|
||||
throw new ReviewModeCaseManagerException("Could not write to the case folder, contact adminstrator", ex);
|
||||
} else if (ex instanceof CaseActionException) {
|
||||
/*
|
||||
* CaseActionExceptions have user friendly error messages.
|
||||
*/
|
||||
} catch (CaseActionException ex) {
|
||||
throw new ReviewModeCaseManagerException(String.format("Could not open the case (%s), contract administrator", ex.getMessage()), ex);
|
||||
} else if (ex instanceof ReviewModeCaseManagerException) {
|
||||
throw (ReviewModeCaseManagerException) ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())
|
||||
&& null != evt.getOldValue()
|
||||
&& null == evt.getNewValue()) {
|
||||
/*
|
||||
* When a case is closed, release the coordination service lock on
|
||||
* the case folder. This must be done in the EDT because it was
|
||||
* acquired in the EDT via openCase().
|
||||
*/
|
||||
if (null != currentCaseLock) {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
try {
|
||||
currentCaseLock.release();
|
||||
currentCaseLock = null;
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to release the coordination service lock with path %s", currentCaseLock.getNodePath()), ex);
|
||||
currentCaseLock = null;
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException | InvocationTargetException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to release the coordination service lock with path %s", currentCaseLock.getNodePath()), ex);
|
||||
currentCaseLock = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,9 +49,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
|
||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestSettingsPanel.UpdateConfigSwingWorker;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
|
||||
/*
|
||||
* A utility class for loading and saving shared configuration data
|
||||
|
Loading…
x
Reference in New Issue
Block a user