diff --git a/.gitattributes b/.gitattributes
index cd5271c982..8749e5dadb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -13,3 +13,9 @@ Doxyfile text
*.py text diff=python
*.pl text
+
+# ensure solr scripts that are bash scripts not ending with.sh are lf instead of crlf
+/KeywordSearch/solr/bin/autopsy-solr eol=lf
+/KeywordSearch/solr/bin/init.d/solr eol=lf
+/KeywordSearch/solr/bin/post eol=lf
+/KeywordSearch/solr/bin/solr eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index faa1b92a94..8338c52863 100755
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
/*/build/
*/nbproject/private/*
/nbproject/private/*
+/apidiff_output/
/Core/release/
/Core/src/org/sleuthkit/autopsy/coreutils/Version.properties
@@ -23,7 +24,12 @@
!/CoreLibs/nbproject/project.xml
!/CoreLibs/nbproject/project.properties
-/Core/test/qa-functional/data/
+/CoreTestLibs/release/
+/CoreTestLibs/build/
+/CoreTestLibs/dist/
+
+/Core/test/qa-functional/data/*
+!/Core/test/qa-functional/data/PasswordDetection_img1_v1.img
/KeywordSearch/release/
/KeywordSearch/build/
@@ -69,6 +75,7 @@ genfiles.properties
*~
/netbeans-plat
/docs/doxygen-user/user-docs
+/docs/doxygen-dev/build-docs
/jdiff-javadocs/*
/jdiff-logs/*
/gen_version.txt
@@ -101,3 +108,4 @@ hs_err_pid*.log
/thirdparty/yara/YaraJNIWrapper/nbproject/private/
/thirdparty/yara/yarabridge/.vs/
+*/path_list.txt
diff --git a/Core/build.xml b/Core/build.xml
index 73bda54795..deb035b609 100644
--- a/Core/build.xml
+++ b/Core/build.xml
@@ -10,6 +10,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -21,6 +31,17 @@
+
+
+
+
+
+
@@ -73,32 +94,19 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
+
@@ -126,16 +134,16 @@
-
-
-
-
+
+
+
+
+ tofile="${ext.dir}/SparseBitSet-1.1.jar"/>
@@ -149,12 +157,11 @@
-
+
-
@@ -178,11 +185,16 @@
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/ivy.xml b/Core/ivy.xml
index a4e10cc605..cedeba9b2d 100644
--- a/Core/ivy.xml
+++ b/Core/ivy.xml
@@ -3,58 +3,86 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
-
+
+
+
+
-
-
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/ivysettings.xml b/Core/ivysettings.xml
index 9c3b496314..fd792f6844 100644
--- a/Core/ivysettings.xml
+++ b/Core/ivysettings.xml
@@ -6,4 +6,5 @@
+
diff --git a/Core/manifest.mf b/Core/manifest.mf
index da946df7b8..59baf3f8c2 100644
--- a/Core/manifest.mf
+++ b/Core/manifest.mf
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.core/10
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
-OpenIDE-Module-Implementation-Version: 34
+OpenIDE-Module-Implementation-Version: 37
OpenIDE-Module-Requires: org.openide.windows.WindowManager
AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index e46293370f..07dc595f2f 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -1,133 +1,83 @@
-file.reference.activemq-all-5.16.0.jar=release\\modules\\ext\\activemq-all-5.16.0.jar
-file.reference.animal-sniffer-annotations-1.17.jar=release\\modules\\ext\\animal-sniffer-annotations-1.17.jar
-file.reference.api-common-1.7.0.jar=release\\modules\\ext\\api-common-1.7.0.jar
-file.reference.batik-awt-util-1.6.jar=release\\modules\\ext\\batik-awt-util-1.6.jar
-file.reference.batik-dom-1.6.jar=release\\modules\\ext\\batik-dom-1.6.jar
-file.reference.batik-svg-dom-1.6.jar=release\\modules\\ext\\batik-svg-dom-1.6.jar
-file.reference.batik-svggen-1.6.jar=release\\modules\\ext\\batik-svggen-1.6.jar
-file.reference.batik-util-1.6.jar=release\\modules\\ext\\batik-util-1.6.jar
-file.reference.batik-xml-1.6.jar=release\\modules\\ext\\batik-xml-1.6.jar
-file.reference.bcpkix-jdk15on-1.54.jar=release\\modules\\ext\\bcpkix-jdk15on-1.54.jar
-file.reference.bcprov-ext-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-ext-jdk15on-1.54.jar
-file.reference.bcprov-jdk15on-1.52.jar=release\\modules\\ext\\bcprov-jdk15on-1.52.jar
-file.reference.bcprov-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-jdk15on-1.54.jar
-file.reference.byte-buddy-1.10.13.jar=release\\modules\\ext\\byte-buddy-1.10.13.jar
-file.reference.byte-buddy-agent-1.10.13.jar=release\\modules\\ext\\byte-buddy-agent-1.10.13.jar
-file.reference.c3p0-0.9.5.jar=release\\modules\\ext\\c3p0-0.9.5.jar
-file.reference.checker-compat-qual-2.5.3.jar=release\\modules\\ext\\checker-compat-qual-2.5.3.jar
-file.reference.commons-beanutils-1.9.2.jar=release\\modules\\ext\\commons-beanutils-1.9.2.jar
-file.reference.commons-codec-1.11.jar=release\\modules\\ext\\commons-codec-1.11.jar
-file.reference.commons-collections-3.2.2.jar=release\\modules\\ext\\commons-collections-3.2.2.jar
-file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.1.jar
-file.reference.commons-digester-1.8.1.jar=release\\modules\\ext\\commons-digester-1.8.1.jar
-file.reference.commons-lang-2.6.jar=release\\modules\\ext\\commons-lang-2.6.jar
-file.reference.commons-lang3-3.5.jar=release\\modules\\ext\\commons-lang3-3.5.jar
-file.reference.commons-logging-1.2.jar=release\\modules\\ext\\commons-logging-1.2.jar
-file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
-file.reference.commons-validator-1.6.jar=release\\modules\\ext\\commons-validator-1.6.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.DatCon.jar=release\\modules\\ext\\DatCon.jar
-file.reference.decodetect-core-0.3.jar=release\\modules\\ext\\decodetect-core-0.3.jar
-file.reference.error_prone_annotations-2.3.2.jar=release\\modules\\ext\\error_prone_annotations-2.3.2.jar
-file.reference.failureaccess-1.0.1.jar=release\\modules\\ext\\failureaccess-1.0.1.jar
-file.reference.gax-1.44.0.jar=release\\modules\\ext\\gax-1.44.0.jar
-file.reference.gax-grpc-1.44.0.jar=release\\modules\\ext\\gax-grpc-1.44.0.jar
-file.reference.gax-httpjson-0.61.0.jar=release\\modules\\ext\\gax-httpjson-0.61.0.jar
-file.reference.google-api-client-1.27.0.jar=release\\modules\\ext\\google-api-client-1.27.0.jar
-file.reference.google-api-services-translate-v2-rev20170525-1.27.0.jar=release\\modules\\ext\\google-api-services-translate-v2-rev20170525-1.27.0.jar
-file.reference.google-auth-library-credentials-0.15.0.jar=release\\modules\\ext\\google-auth-library-credentials-0.15.0.jar
-file.reference.google-auth-library-oauth2-http-0.15.0.jar=release\\modules\\ext\\google-auth-library-oauth2-http-0.15.0.jar
-file.reference.google-cloud-core-1.70.0.jar=release\\modules\\ext\\google-cloud-core-1.70.0.jar
-file.reference.google-cloud-core-grpc-1.70.0.jar=release\\modules\\ext\\google-cloud-core-grpc-1.70.0.jar
-file.reference.google-cloud-core-http-1.70.0.jar=release\\modules\\ext\\google-cloud-core-http-1.70.0.jar
-file.reference.google-cloud-translate-1.70.0.jar=release\\modules\\ext\\google-cloud-translate-1.70.0.jar
-file.reference.google-http-client-1.29.0.jar=release\\modules\\ext\\google-http-client-1.29.0.jar
-file.reference.google-http-client-appengine-1.29.0.jar=release\\modules\\ext\\google-http-client-appengine-1.29.0.jar
-file.reference.google-http-client-jackson2-1.29.0.jar=release\\modules\\ext\\google-http-client-jackson2-1.29.0.jar
-file.reference.google-oauth-client-1.28.0.jar=release\\modules\\ext\\google-oauth-client-1.28.0.jar
-file.reference.grpc-alts-1.19.0.jar=release\\modules\\ext\\grpc-alts-1.19.0.jar
-file.reference.grpc-auth-1.19.0.jar=release\\modules\\ext\\grpc-auth-1.19.0.jar
-file.reference.grpc-context-1.19.0.jar=release\\modules\\ext\\grpc-context-1.19.0.jar
-file.reference.grpc-core-1.19.0.jar=release\\modules\\ext\\grpc-core-1.19.0.jar
-file.reference.grpc-grpclb-1.19.0.jar=release\\modules\\ext\\grpc-grpclb-1.19.0.jar
-file.reference.grpc-netty-shaded-1.19.0.jar=release\\modules\\ext\\grpc-netty-shaded-1.19.0.jar
-file.reference.grpc-protobuf-1.19.0.jar=release\\modules\\ext\\grpc-protobuf-1.19.0.jar
-file.reference.grpc-protobuf-lite-1.19.0.jar=release\\modules\\ext\\grpc-protobuf-lite-1.19.0.jar
-file.reference.grpc-stub-1.19.0.jar=release\\modules\\ext\\grpc-stub-1.19.0.jar
-file.reference.gson-2.7.jar=release\\modules\\ext\\gson-2.7.jar
-file.reference.guava-27.1-android.jar=release\\modules\\ext\\guava-27.1-android.jar
-file.reference.httpclient-4.5.5.jar=release\\modules\\ext\\httpclient-4.5.5.jar
-file.reference.httpcore-4.4.9.jar=release\\modules\\ext\\httpcore-4.4.9.jar
-file.reference.icepdf-core-6.2.2.jar=release\\modules\\ext\\icepdf-core-6.2.2.jar
-file.reference.icepdf-viewer-6.2.2.jar=release\\modules\\ext\\icepdf-viewer-6.2.2.jar
-file.reference.istack-commons-runtime-3.0.11.jar=release/modules/ext/istack-commons-runtime-3.0.11.jar
-file.reference.j2objc-annotations-1.1.jar=release\\modules\\ext\\j2objc-annotations-1.1.jar
-file.reference.jackcess-2.2.0.jar=release\\modules\\ext\\jackcess-2.2.0.jar
-file.reference.jackcess-encrypt-2.1.4.jar=release\\modules\\ext\\jackcess-encrypt-2.1.4.jar
-file.reference.jackson-annotations-2.9.0.jar=release\\modules\\ext\\jackson-annotations-2.9.0.jar
-file.reference.jackson-core-2.9.7.jar=release\\modules\\ext\\jackson-core-2.9.7.jar
-file.reference.jackson-databind-2.9.7.jar=release\\modules\\ext\\jackson-databind-2.9.7.jar
-file.reference.jai_core-1.1.3.jar=release\\modules\\ext\\jai_core-1.1.3.jar
-file.reference.jai_imageio-1.1.jar=release\\modules\\ext\\jai_imageio-1.1.jar
-file.reference.javax.annotation-api-1.3.2.jar=release\\modules\\ext\\javax.annotation-api-1.3.2.jar
-file.reference.javax.ws.rs-api-2.0.jar=release\\modules\\ext\\javax.ws.rs-api-2.0.jar
-file.reference.jaxb-api-2.3.1.jar=release\\modules\\ext\\jaxb-api-2.3.1.jar
-file.reference.jaxb-runtime-2.3.3.jar=release\\modules\\ext\\jaxb-runtime-2.3.3.jar
-file.reference.jcommon-1.0.23.jar=release/modules/ext/jcommon-1.0.23.jar
-file.reference.jdom-2.0.5-contrib.jar=release\\modules\\ext\\jdom-2.0.5-contrib.jar
-file.reference.jdom-2.0.5.jar=release\\modules\\ext\\jdom-2.0.5.jar
-file.reference.jericho-html-3.3.jar=release\\modules\\ext\\jericho-html-3.3.jar
-file.reference.jfreechart-1.0.19.jar=release/modules/ext/jfreechart-1.0.19.jar
-file.reference.jgraphx-4.1.0.jar=release\\modules\\ext\\jgraphx-4.1.0.jar
-file.reference.jline-0.9.94.jar=release\\modules\\ext\\jline-0.9.94.jar
-file.reference.jsoup-1.10.3.jar=release\\modules\\ext\\jsoup-1.10.3.jar
-file.reference.jsr305-3.0.2.jar=release\\modules\\ext\\jsr305-3.0.2.jar
-file.reference.junit-3.8.1.jar=release\\modules\\ext\\junit-3.8.1.jar
-file.reference.jutf7-1.0.0.jar=release\\modules\\ext\\jutf7-1.0.0.jar
-file.reference.jxmapviewer2-2.4.jar=release\\modules\\ext\\jxmapviewer2-2.4.jar
-file.reference.jython-standalone-2.7.2.jar=release\\modules\\ext\\jython-standalone-2.7.2.jar
-file.reference.libphonenumber-3.5.jar=release\\modules\\ext\\libphonenumber-3.5.jar
-file.reference.listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar=release\\modules\\ext\\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
-file.reference.log4j-1.2.16.jar=release\\modules\\ext\\log4j-1.2.16.jar
-file.reference.mchange-commons-java-0.2.9.jar=release\\modules\\ext\\mchange-commons-java-0.2.9.jar
-file.reference.metadata-extractor-2.11.0.jar=release\\modules\\ext\\metadata-extractor-2.11.0.jar
-file.reference.mockito-core-3.5.7.jar=release\\modules\\ext\\mockito-core-3.5.7.jar
-file.reference.netty-3.7.0.Final.jar=release\\modules\\ext\\netty-3.7.0.Final.jar
-file.reference.objenesis-3.1.jar=release\\modules\\ext\\objenesis-3.1.jar
-file.reference.okhttp-2.7.5.jar=release\\modules\\ext\\okhttp-2.7.5.jar
-file.reference.okio-1.6.0.jar=release\\modules\\ext\\okio-1.6.0.jar
-file.reference.opencensus-api-0.19.2.jar=release\\modules\\ext\\opencensus-api-0.19.2.jar
-file.reference.opencensus-contrib-grpc-metrics-0.19.2.jar=release\\modules\\ext\\opencensus-contrib-grpc-metrics-0.19.2.jar
-file.reference.opencensus-contrib-http-util-0.19.2.jar=release\\modules\\ext\\opencensus-contrib-http-util-0.19.2.jar
-file.reference.opennlp-tools-1.9.1.jar=release\\modules\\ext\\opennlp-tools-1.9.1.jar
-file.reference.postgresql-42.2.18.jar=release\\modules\\ext\\postgresql-42.2.18.jar
-file.reference.proto-google-cloud-translate-v3beta1-0.53.0.jar=release\\modules\\ext\\proto-google-cloud-translate-v3beta1-0.53.0.jar
-file.reference.proto-google-common-protos-1.15.0.jar=release\\modules\\ext\\proto-google-common-protos-1.15.0.jar
-file.reference.proto-google-iam-v1-0.12.0.jar=release\\modules\\ext\\proto-google-iam-v1-0.12.0.jar
-file.reference.protobuf-java-3.7.0.jar=release\\modules\\ext\\protobuf-java-3.7.0.jar
-file.reference.protobuf-java-util-3.7.0.jar=release\\modules\\ext\\protobuf-java-util-3.7.0.jar
-file.reference.Rejistry-1.1-SNAPSHOT.jar=release\\modules\\ext\\Rejistry-1.1-SNAPSHOT.jar
-file.reference.sevenzipjbinding-AllPlatforms.jar=release\\modules\\ext\\sevenzipjbinding-AllPlatforms.jar
-file.reference.sevenzipjbinding.jar=release\\modules\\ext\\sevenzipjbinding.jar
-file.reference.sleuthkit-4.10.1.jar=release/modules/ext/sleuthkit-4.10.1.jar
-file.reference.sleuthkit-caseuco-4.10.1.jar=release/modules/ext/sleuthkit-caseuco-4.10.1.jar
-file.reference.slf4j-api-1.7.6.jar=release\\modules\\ext\\slf4j-api-1.7.6.jar
-file.reference.slf4j-log4j12-1.7.6.jar=release\\modules\\ext\\slf4j-log4j12-1.7.6.jar
-file.reference.SparseBitSet-1.1.jar=release\\modules\\ext\\SparseBitSet-1.1.jar
-file.reference.sqlite-jdbc-3.25.2.jar=release\\modules\\ext\\sqlite-jdbc-3.25.2.jar
-file.reference.StixLib.jar=release\\modules\\ext\\StixLib.jar
-file.reference.threetenbp-1.3.3.jar=release\\modules\\ext\\threetenbp-1.3.3.jar
-file.reference.webp-imageio-sejda-0.1.0.jar=release\\modules\\ext\\webp-imageio-sejda-0.1.0.jar
-file.reference.xmpcore-5.1.3.jar=release\\modules\\ext\\xmpcore-5.1.3.jar
+file.reference.activemq-all-5.16.4.jar=release/modules/ext/activemq-all-5.16.4.jar
+file.reference.audience-annotations-0.12.0.jar=release/modules/ext/audience-annotations-0.12.0.jar
+file.reference.batik-awt-util-1.14.jar=release/modules/ext/batik-awt-util-1.14.jar
+file.reference.batik-dom-1.14.jar=release/modules/ext/batik-dom-1.14.jar
+file.reference.batik-svg-dom-1.14.jar=release/modules/ext/batik-svg-dom-1.14.jar
+file.reference.batik-svggen-1.14.jar=release/modules/ext/batik-svggen-1.14.jar
+file.reference.batik-util-1.14.jar=release/modules/ext/batik-util-1.14.jar
+file.reference.batik-xml-1.14.jar=release/modules/ext/batik-xml-1.14.jar
+file.reference.bcpkix-jdk15on-1.70.jar=release/modules/ext/bcpkix-jdk15on-1.70.jar
+file.reference.bcprov-ext-jdk15on-1.70.jar=release/modules/ext/bcprov-ext-jdk15on-1.70.jar
+file.reference.bcprov-jdk15on-1.70.jar=release/modules/ext/bcprov-jdk15on-1.70.jar
+file.reference.c3p0-0.9.5.5.jar=release/modules/ext/c3p0-0.9.5.5.jar
+file.reference.checker-qual-3.12.0.jar=release/modules/ext/checker-qual-3.12.0.jar
+file.reference.commons-dbcp2-2.9.0.jar=release/modules/ext/commons-dbcp2-2.9.0.jar
+file.reference.commons-io-2.11.0.jar=release/modules/ext/commons-io-2.11.0.jar
+file.reference.commons-lang3-3.10.jar=release/modules/ext/commons-lang3-3.10.jar
+file.reference.commons-logging-1.2.jar=release/modules/ext/commons-logging-1.2.jar
+file.reference.commons-pool2-2.10.0.jar=release/modules/ext/commons-pool2-2.10.0.jar
+file.reference.curator-client-5.2.1.jar=release/modules/ext/curator-client-5.2.1.jar
+file.reference.curator-framework-5.2.1.jar=release/modules/ext/curator-framework-5.2.1.jar
+file.reference.curator-recipes-5.2.1.jar=release/modules/ext/curator-recipes-5.2.1.jar
+file.reference.DatCon.jar=release/modules/ext/DatCon.jar
+file.reference.decodetect-core-0.3.jar=release/modules/ext/decodetect-core-0.3.jar
+file.reference.error_prone_annotations-2.11.0.jar=release/modules/ext/error_prone_annotations-2.11.0.jar
+file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.jar
+file.reference.guava-31.1-jre.jar=release/modules/ext/guava-31.1-jre.jar
+file.reference.icepdf-core-6.2.2.jar=release/modules/ext/icepdf-core-6.2.2.jar
+file.reference.icepdf-viewer-6.2.2.jar=release/modules/ext/icepdf-viewer-6.2.2.jar
+file.reference.j2objc-annotations-1.3.jar=release/modules/ext/j2objc-annotations-1.3.jar
+file.reference.jackcess-4.0.1.jar=release/modules/ext/jackcess-4.0.1.jar
+file.reference.jackcess-encrypt-4.0.1.jar=release/modules/ext/jackcess-encrypt-4.0.1.jar
+file.reference.jai_core-1.1.3.jar=release/modules/ext/jai_core-1.1.3.jar
+file.reference.jai_imageio-1.1.jar=release/modules/ext/jai_imageio-1.1.jar
+file.reference.java-diff-utils-4.11.jar=release/modules/ext/java-diff-utils-4.11.jar
+file.reference.javax.ws.rs-api-2.1.1.jar=release/modules/ext/javax.ws.rs-api-2.1.1.jar
+file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar
+file.reference.jfreechart-1.5.3.jar=release/modules/ext/jfreechart-1.5.3.jar
+file.reference.jgraphx-4.2.2.jar=release/modules/ext/jgraphx-4.2.2.jar
+file.reference.jsoup-1.14.3.jar=release/modules/ext/jsoup-1.14.3.jar
+file.reference.jsr305-3.0.2.jar=release/modules/ext/jsr305-3.0.2.jar
+file.reference.jutf7-1.0.0.jar=release/modules/ext/jutf7-1.0.0.jar
+file.reference.jxmapviewer2-2.6.jar=release/modules/ext/jxmapviewer2-2.6.jar
+file.reference.jython-standalone-2.7.2.jar=release/modules/ext/jython-standalone-2.7.2.jar
+file.reference.libphonenumber-8.12.45.jar=release/modules/ext/libphonenumber-8.12.45.jar
+file.reference.listenablefuture-1.0.jar=release/modules/ext/listenablefuture-1.0.jar
+file.reference.logback-classic-1.2.10.jar=release/modules/ext/logback-classic-1.2.10.jar
+file.reference.logback-core-1.2.10.jar=release/modules/ext/logback-core-1.2.10.jar
+file.reference.mchange-commons-java-0.2.20.jar=release/modules/ext/mchange-commons-java-0.2.20.jar
+file.reference.metadata-extractor-2.17.0.jar=release/modules/ext/metadata-extractor-2.17.0.jar
+file.reference.netty-buffer-4.1.73.Final.jar=release/modules/ext/netty-buffer-4.1.73.Final.jar
+file.reference.netty-codec-4.1.73.Final.jar=release/modules/ext/netty-codec-4.1.73.Final.jar
+file.reference.netty-common-4.1.73.Final.jar=release/modules/ext/netty-common-4.1.73.Final.jar
+file.reference.netty-handler-4.1.73.Final.jar=release/modules/ext/netty-handler-4.1.73.Final.jar
+file.reference.netty-resolver-4.1.73.Final.jar=release/modules/ext/netty-resolver-4.1.73.Final.jar
+file.reference.netty-tcnative-2.0.48.Final.jar=release/modules/ext/netty-tcnative-2.0.48.Final.jar
+file.reference.netty-tcnative-classes-2.0.48.Final.jar=release/modules/ext/netty-tcnative-classes-2.0.48.Final.jar
+file.reference.netty-transport-4.1.73.Final.jar=release/modules/ext/netty-transport-4.1.73.Final.jar
+file.reference.netty-transport-classes-epoll-4.1.73.Final.jar=release/modules/ext/netty-transport-classes-epoll-4.1.73.Final.jar
+file.reference.netty-transport-native-epoll-4.1.73.Final.jar=release/modules/ext/netty-transport-native-epoll-4.1.73.Final.jar
+file.reference.netty-transport-native-unix-common-4.1.73.Final.jar=release/modules/ext/netty-transport-native-unix-common-4.1.73.Final.jar
+file.reference.okhttp-2.7.5.jar=release/modules/ext/okhttp-2.7.5.jar
+file.reference.okio-1.6.0.jar=release/modules/ext/okio-1.6.0.jar
+file.reference.postgresql-42.3.5.jar=release/modules/ext/postgresql-42.3.5.jar
+file.reference.Rejistry-1.1-SNAPSHOT.jar=release/modules/ext/Rejistry-1.1-SNAPSHOT.jar
+file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
+file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
+file.reference.sleuthkit-4.11.1.jar=release/modules/ext/sleuthkit-4.11.1.jar
+file.reference.sleuthkit-caseuco-4.11.1.jar=release/modules/ext/sleuthkit-caseuco-4.11.1.jar
+file.reference.snakeyaml-1.30.jar=release/modules/ext/snakeyaml-1.30.jar
+file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
+file.reference.spotbugs-annotations-4.6.0.jar=release/modules/ext/spotbugs-annotations-4.6.0.jar
+file.reference.sqlite-jdbc-3.36.0.3.jar=release/modules/ext/sqlite-jdbc-3.36.0.3.jar
+file.reference.xmpcore-6.1.11.jar=release/modules/ext/xmpcore-6.1.11.jar
file.reference.YaraJNIWrapper.jar=release/modules/ext/YaraJNIWrapper.jar
-file.reference.zookeeper-3.4.6.jar=release\\modules\\ext\\zookeeper-3.4.6.jar
+file.reference.zookeeper-3.8.0.jar=release/modules/ext/zookeeper-3.8.0.jar
+file.reference.zookeeper-jute-3.8.0.jar=release/modules/ext/zookeeper-jute-3.8.0.jar
javac.source=11
javac.compilerargs=-Xlint -Xlint:-serial
license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/
nbm.module.author=Brian Carrier
nbm.needs.restart=true
-source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
-spec.version.base=10.22
+spec.version.base=10.24
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index f3fb59145e..79f393466c 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -269,6 +269,11 @@
org.netbeans.modules.nbjunit
+
+ org.sleuthkit.autopsy.coretestlibs
+
+
+
qa-functional
@@ -293,6 +298,10 @@
+
+ org.sleuthkit.autopsy.coretestlibs
+
+
@@ -336,509 +345,365 @@
org.sleuthkit.autopsy.textextractors.configs
org.sleuthkit.autopsy.textsummarizer
org.sleuthkit.autopsy.texttranslation
+ org.sleuthkit.autopsy.url.analytics
org.sleuthkit.datamodel
org.sleuthkit.datamodel.blackboardutils
org.sleuthkit.datamodel.blackboardutils.attributes
- ext/batik-xml-1.6.jar
- release\modules\ext\batik-xml-1.6.jar
+ ext/activemq-all-5.16.4.jar
+ release/modules/ext/activemq-all-5.16.4.jar
- ext/commons-digester-1.8.1.jar
- release\modules\ext\commons-digester-1.8.1.jar
+ ext/audience-annotations-0.12.0.jar
+ release/modules/ext/audience-annotations-0.12.0.jar
- ext/jai_core-1.1.3.jar
- release\modules\ext\jai_core-1.1.3.jar
+ ext/batik-awt-util-1.14.jar
+ release/modules/ext/batik-awt-util-1.14.jar
- ext/gax-grpc-1.44.0.jar
- release\modules\ext\gax-grpc-1.44.0.jar
+ ext/batik-dom-1.14.jar
+ release/modules/ext/batik-dom-1.14.jar
- ext/failureaccess-1.0.1.jar
- release\modules\ext\failureaccess-1.0.1.jar
+ ext/batik-svg-dom-1.14.jar
+ release/modules/ext/batik-svg-dom-1.14.jar
- ext/grpc-protobuf-1.19.0.jar
- release\modules\ext\grpc-protobuf-1.19.0.jar
+ ext/batik-svggen-1.14.jar
+ release/modules/ext/batik-svggen-1.14.jar
- ext/opencensus-api-0.19.2.jar
- release\modules\ext\opencensus-api-0.19.2.jar
+ ext/batik-util-1.14.jar
+ release/modules/ext/batik-util-1.14.jar
- ext/batik-svg-dom-1.6.jar
- release\modules\ext\batik-svg-dom-1.6.jar
+ ext/batik-xml-1.14.jar
+ release/modules/ext/batik-xml-1.14.jar
- ext/gax-httpjson-0.61.0.jar
- release\modules\ext\gax-httpjson-0.61.0.jar
+ ext/bcpkix-jdk15on-1.70.jar
+ release/modules/ext/bcpkix-jdk15on-1.70.jar
- ext/sevenzipjbinding.jar
- release\modules\ext\sevenzipjbinding.jar
+ ext/bcprov-ext-jdk15on-1.70.jar
+ release/modules/ext/bcprov-ext-jdk15on-1.70.jar
- ext/mchange-commons-java-0.2.9.jar
- release\modules\ext\mchange-commons-java-0.2.9.jar
+ ext/bcprov-jdk15on-1.70.jar
+ release/modules/ext/bcprov-jdk15on-1.70.jar
- ext/api-common-1.7.0.jar
- release\modules\ext\api-common-1.7.0.jar
+ ext/c3p0-0.9.5.5.jar
+ release/modules/ext/c3p0-0.9.5.5.jar
- ext/jackson-databind-2.9.7.jar
- release\modules\ext\jackson-databind-2.9.7.jar
+ ext/checker-qual-3.12.0.jar
+ release/modules/ext/checker-qual-3.12.0.jar
- ext/okhttp-2.7.5.jar
- release\modules\ext\okhttp-2.7.5.jar
+ ext/commons-dbcp2-2.9.0.jar
+ release/modules/ext/commons-dbcp2-2.9.0.jar
- ext/proto-google-cloud-translate-v3beta1-0.53.0.jar
- release\modules\ext\proto-google-cloud-translate-v3beta1-0.53.0.jar
+ ext/commons-io-2.11.0.jar
+ release/modules/ext/commons-io-2.11.0.jar
- ext/byte-buddy-1.10.13.jar
- release\modules\ext\byte-buddy-1.10.13.jar
+ ext/commons-lang3-3.10.jar
+ release/modules/ext/commons-lang3-3.10.jar
- ext/error_prone_annotations-2.3.2.jar
- release\modules\ext\error_prone_annotations-2.3.2.jar
+ ext/commons-logging-1.2.jar
+ release/modules/ext/commons-logging-1.2.jar
- ext/libphonenumber-3.5.jar
- release\modules\ext\libphonenumber-3.5.jar
+ ext/commons-pool2-2.10.0.jar
+ release/modules/ext/commons-pool2-2.10.0.jar
- ext/StixLib.jar
- release\modules\ext\StixLib.jar
+ ext/curator-client-5.2.1.jar
+ release/modules/ext/curator-client-5.2.1.jar
- ext/google-auth-library-credentials-0.15.0.jar
- release\modules\ext\google-auth-library-credentials-0.15.0.jar
-
-
- ext/grpc-auth-1.19.0.jar
- release\modules\ext\grpc-auth-1.19.0.jar
-
-
- ext/j2objc-annotations-1.1.jar
- release\modules\ext\j2objc-annotations-1.1.jar
-
-
- ext/metadata-extractor-2.11.0.jar
- release\modules\ext\metadata-extractor-2.11.0.jar
-
-
- ext/commons-codec-1.11.jar
- release\modules\ext\commons-codec-1.11.jar
-
-
- ext/postgresql-42.2.18.jar
- release\modules\ext\postgresql-42.2.18.jar
-
-
- ext/commons-pool2-2.4.2.jar
- release\modules\ext\commons-pool2-2.4.2.jar
-
-
- ext/jxmapviewer2-2.4.jar
- release\modules\ext\jxmapviewer2-2.4.jar
-
-
- ext/jdom-2.0.5-contrib.jar
- release\modules\ext\jdom-2.0.5-contrib.jar
-
-
- ext/xmpcore-5.1.3.jar
- release\modules\ext\xmpcore-5.1.3.jar
-
-
- ext/batik-util-1.6.jar
- release\modules\ext\batik-util-1.6.jar
-
-
- ext/javax.annotation-api-1.3.2.jar
- release\modules\ext\javax.annotation-api-1.3.2.jar
-
-
- ext/jgraphx-4.1.0.jar
- release\modules\ext\jgraphx-4.1.0.jar
+ ext/curator-framework-5.2.1.jar
+ release/modules/ext/curator-framework-5.2.1.jar
+<<<<<<< HEAD
ext/jython-standalone-2.7.2.jar
release\modules\ext\jython-standalone-2.7.2.jar
ext/jline-0.9.94.jar
release\modules\ext\jline-0.9.94.jar
+=======
+ ext/curator-recipes-5.2.1.jar
+ release/modules/ext/curator-recipes-5.2.1.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
ext/DatCon.jar
- release\modules\ext\DatCon.jar
-
-
- ext/okio-1.6.0.jar
- release\modules\ext\okio-1.6.0.jar
-
-
- ext/bcprov-jdk15on-1.54.jar
- release\modules\ext\bcprov-jdk15on-1.54.jar
-
-
- ext/curator-framework-2.8.0.jar
- release\modules\ext\curator-framework-2.8.0.jar
-
-
- ext/commons-dbcp2-2.1.1.jar
- release\modules\ext\commons-dbcp2-2.1.1.jar
-
-
- ext/google-http-client-appengine-1.29.0.jar
- release\modules\ext\google-http-client-appengine-1.29.0.jar
-
-
- ext/proto-google-iam-v1-0.12.0.jar
- release\modules\ext\proto-google-iam-v1-0.12.0.jar
-
-
- ext/jackcess-encrypt-2.1.4.jar
- release\modules\ext\jackcess-encrypt-2.1.4.jar
-
-
- ext/google-http-client-1.29.0.jar
- release\modules\ext\google-http-client-1.29.0.jar
-
-
- ext/opennlp-tools-1.9.1.jar
- release\modules\ext\opennlp-tools-1.9.1.jar
-
-
- ext/bcprov-ext-jdk15on-1.54.jar
- release\modules\ext\bcprov-ext-jdk15on-1.54.jar
-
-
- ext/google-cloud-core-1.70.0.jar
- release\modules\ext\google-cloud-core-1.70.0.jar
-
-
- ext/protobuf-java-3.7.0.jar
- release\modules\ext\protobuf-java-3.7.0.jar
-
-
- ext/bcpkix-jdk15on-1.54.jar
- release\modules\ext\bcpkix-jdk15on-1.54.jar
-
-
- ext/sqlite-jdbc-3.25.2.jar
- release\modules\ext\sqlite-jdbc-3.25.2.jar
-
-
- ext/grpc-protobuf-lite-1.19.0.jar
- release\modules\ext\grpc-protobuf-lite-1.19.0.jar
-
-
- ext/httpcore-4.4.9.jar
- release\modules\ext\httpcore-4.4.9.jar
-
-
- ext/guava-27.1-android.jar
- release\modules\ext\guava-27.1-android.jar
-
-
- ext/bcprov-jdk15on-1.52.jar
- release\modules\ext\bcprov-jdk15on-1.52.jar
-
-
- ext/checker-compat-qual-2.5.3.jar
- release\modules\ext\checker-compat-qual-2.5.3.jar
-
-
- ext/animal-sniffer-annotations-1.17.jar
- release\modules\ext\animal-sniffer-annotations-1.17.jar
-
-
- ext/gax-1.44.0.jar
- release\modules\ext\gax-1.44.0.jar
-
-
- ext/jsoup-1.10.3.jar
- release\modules\ext\jsoup-1.10.3.jar
-
-
- ext/YaraJNIWrapper.jar
- release/modules/ext/YaraJNIWrapper.jar
-
-
- ext/grpc-context-1.19.0.jar
- release\modules\ext\grpc-context-1.19.0.jar
-
-
- ext/jackcess-2.2.0.jar
- release\modules\ext\jackcess-2.2.0.jar
-
-
- ext/slf4j-log4j12-1.7.6.jar
- release\modules\ext\slf4j-log4j12-1.7.6.jar
-
-
- ext/jericho-html-3.3.jar
- release\modules\ext\jericho-html-3.3.jar
-
-
- ext/google-cloud-core-grpc-1.70.0.jar
- release\modules\ext\google-cloud-core-grpc-1.70.0.jar
-
-
- ext/commons-validator-1.6.jar
- release\modules\ext\commons-validator-1.6.jar
-
-
- ext/slf4j-api-1.7.6.jar
- release\modules\ext\slf4j-api-1.7.6.jar
+ release/modules/ext/DatCon.jar
ext/decodetect-core-0.3.jar
- release\modules\ext\decodetect-core-0.3.jar
+ release/modules/ext/decodetect-core-0.3.jar
- ext/mockito-core-3.5.7.jar
- release\modules\ext\mockito-core-3.5.7.jar
+ ext/error_prone_annotations-2.11.0.jar
+ release/modules/ext/error_prone_annotations-2.11.0.jar
- ext/httpclient-4.5.5.jar
- release\modules\ext\httpclient-4.5.5.jar
+ ext/failureaccess-1.0.1.jar
+ release/modules/ext/failureaccess-1.0.1.jar
- ext/curator-recipes-2.8.0.jar
- release\modules\ext\curator-recipes-2.8.0.jar
+ ext/guava-31.1-jre.jar
+ release/modules/ext/guava-31.1-jre.jar
- ext/jackson-annotations-2.9.0.jar
- release\modules\ext\jackson-annotations-2.9.0.jar
+ ext/icepdf-core-6.2.2.jar
+ release/modules/ext/icepdf-core-6.2.2.jar
- ext/objenesis-3.1.jar
- release\modules\ext\objenesis-3.1.jar
+ ext/icepdf-viewer-6.2.2.jar
+ release/modules/ext/icepdf-viewer-6.2.2.jar
- ext/jackson-core-2.9.7.jar
- release\modules\ext\jackson-core-2.9.7.jar
+ ext/j2objc-annotations-1.3.jar
+ release/modules/ext/j2objc-annotations-1.3.jar
- ext/commons-lang3-3.5.jar
- release\modules\ext\commons-lang3-3.5.jar
+ ext/jackcess-4.0.1.jar
+ release/modules/ext/jackcess-4.0.1.jar
- ext/log4j-1.2.16.jar
- release\modules\ext\log4j-1.2.16.jar
+ ext/jackcess-encrypt-4.0.1.jar
+ release/modules/ext/jackcess-encrypt-4.0.1.jar
- ext/commons-logging-1.2.jar
- release\modules\ext\commons-logging-1.2.jar
+ ext/jai_core-1.1.3.jar
+ release/modules/ext/jai_core-1.1.3.jar
- ext/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
- release\modules\ext\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
-
-
- ext/protobuf-java-util-3.7.0.jar
- release\modules\ext\protobuf-java-util-3.7.0.jar
+ ext/jai_imageio-1.1.jar
+ release/modules/ext/jai_imageio-1.1.jar
+<<<<<<< HEAD
ext/jaxb-api-2.3.1.jar
release\modules\ext\jaxb-api-2.3.1.jar
ext/commons-collections-3.2.2.jar
release\modules\ext\commons-collections-3.2.2.jar
+=======
+ ext/java-diff-utils-4.11.jar
+ release/modules/ext/java-diff-utils-4.11.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
- ext/SparseBitSet-1.1.jar
- release\modules\ext\SparseBitSet-1.1.jar
-
-
- ext/grpc-grpclb-1.19.0.jar
- release\modules\ext\grpc-grpclb-1.19.0.jar
-
-
- ext/batik-svggen-1.6.jar
- release\modules\ext\batik-svggen-1.6.jar
-
-
- ext/c3p0-0.9.5.jar
- release\modules\ext\c3p0-0.9.5.jar
-
-
- ext/zookeeper-3.4.6.jar
- release\modules\ext\zookeeper-3.4.6.jar
-
-
- ext/grpc-alts-1.19.0.jar
- release\modules\ext\grpc-alts-1.19.0.jar
-
-
- ext/sleuthkit-caseuco-4.10.1.jar
- release/modules/ext/sleuthkit-caseuco-4.10.1.jar
+ ext/javax.ws.rs-api-2.1.1.jar
+ release/modules/ext/javax.ws.rs-api-2.1.1.jar
ext/jdom-2.0.5.jar
- release\modules\ext\jdom-2.0.5.jar
+ release/modules/ext/jdom-2.0.5.jar
- ext/gson-2.7.jar
- release\modules\ext\gson-2.7.jar
+ ext/jfreechart-1.5.3.jar
+ release/modules/ext/jfreechart-1.5.3.jar
- ext/google-api-client-1.27.0.jar
- release\modules\ext\google-api-client-1.27.0.jar
+ ext/jgraphx-4.2.2.jar
+ release/modules/ext/jgraphx-4.2.2.jar
+ ext/jsoup-1.14.3.jar
+ release/modules/ext/jsoup-1.14.3.jar
+
+
+ ext/jutf7-1.0.0.jar
+ release/modules/ext/jutf7-1.0.0.jar
+
+
+ ext/jxmapviewer2-2.6.jar
+ release/modules/ext/jxmapviewer2-2.6.jar
+
+
+ ext/jython-standalone-2.7.2.jar
+ release/modules/ext/jython-standalone-2.7.2.jar
+
+
+ ext/libphonenumber-8.12.45.jar
+ release/modules/ext/libphonenumber-8.12.45.jar
+
+
+ ext/listenablefuture-1.0.jar
+ release/modules/ext/listenablefuture-1.0.jar
+
+
+<<<<<<< HEAD
ext/jaxb-runtime-2.3.3.jar
release\modules\ext\jaxb-runtime-2.3.3.jar
ext/opencensus-contrib-http-util-0.19.2.jar
release\modules\ext\opencensus-contrib-http-util-0.19.2.jar
+=======
+ ext/logback-classic-1.2.10.jar
+ release/modules/ext/logback-classic-1.2.10.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
- ext/google-auth-library-oauth2-http-0.15.0.jar
- release\modules\ext\google-auth-library-oauth2-http-0.15.0.jar
+ ext/logback-core-1.2.10.jar
+ release/modules/ext/logback-core-1.2.10.jar
+<<<<<<< HEAD
ext/commons-lang-2.6.jar
release\modules\ext\commons-lang-2.6.jar
+=======
+ ext/mchange-commons-java-0.2.20.jar
+ release/modules/ext/mchange-commons-java-0.2.20.jar
- ext/jsr305-3.0.2.jar
- release\modules\ext\jsr305-3.0.2.jar
+ ext/metadata-extractor-2.17.0.jar
+ release/modules/ext/metadata-extractor-2.17.0.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
- ext/proto-google-common-protos-1.15.0.jar
- release\modules\ext\proto-google-common-protos-1.15.0.jar
+ ext/netty-buffer-4.1.73.Final.jar
+ release/modules/ext/netty-buffer-4.1.73.Final.jar
- ext/netty-3.7.0.Final.jar
- release\modules\ext\netty-3.7.0.Final.jar
+ ext/netty-codec-4.1.73.Final.jar
+ release/modules/ext/netty-codec-4.1.73.Final.jar
- ext/jfreechart-1.0.19.jar
- release/modules/ext/jfreechart-1.0.19.jar
+ ext/netty-common-4.1.73.Final.jar
+ release/modules/ext/netty-common-4.1.73.Final.jar
- ext/opencensus-contrib-grpc-metrics-0.19.2.jar
- release\modules\ext\opencensus-contrib-grpc-metrics-0.19.2.jar
+ ext/netty-handler-4.1.73.Final.jar
+ release/modules/ext/netty-handler-4.1.73.Final.jar
+ ext/netty-resolver-4.1.73.Final.jar
+ release/modules/ext/netty-resolver-4.1.73.Final.jar
+
+
+<<<<<<< HEAD
ext/activemq-all-5.16.0.jar
release\modules\ext\activemq-all-5.16.0.jar
ext/jai_imageio-1.1.jar
release\modules\ext\jai_imageio-1.1.jar
+=======
+ ext/netty-tcnative-2.0.48.Final.jar
+ release/modules/ext/netty-tcnative-2.0.48.Final.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
- ext/junit-3.8.1.jar
- release\modules\ext\junit-3.8.1.jar
+ ext/netty-tcnative-classes-2.0.48.Final.jar
+ release/modules/ext/netty-tcnative-classes-2.0.48.Final.jar
+<<<<<<< HEAD
ext/istack-commons-runtime-3.0.11.jar
release/modules/ext/istack-commons-runtime-3.0.11.jar
ext/curator-client-2.8.0.jar
release\modules\ext\curator-client-2.8.0.jar
+=======
+ ext/netty-transport-4.1.73.Final.jar
+ release/modules/ext/netty-transport-4.1.73.Final.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
- ext/grpc-core-1.19.0.jar
- release\modules\ext\grpc-core-1.19.0.jar
+ ext/netty-transport-classes-epoll-4.1.73.Final.jar
+ release/modules/ext/netty-transport-classes-epoll-4.1.73.Final.jar
- ext/javax.ws.rs-api-2.0.jar
- release\modules\ext\javax.ws.rs-api-2.0.jar
+ ext/netty-transport-native-epoll-4.1.73.Final.jar
+ release/modules/ext/netty-transport-native-epoll-4.1.73.Final.jar
- ext/jcommon-1.0.23.jar
- release/modules/ext/jcommon-1.0.23.jar
+ ext/netty-transport-native-unix-common-4.1.73.Final.jar
+ release/modules/ext/netty-transport-native-unix-common-4.1.73.Final.jar
- ext/icepdf-core-6.2.2.jar
- release\modules\ext\icepdf-core-6.2.2.jar
+ ext/okhttp-2.7.5.jar
+ release/modules/ext/okhttp-2.7.5.jar
+<<<<<<< HEAD
ext/google-cloud-core-http-1.70.0.jar
release\modules\ext\google-cloud-core-http-1.70.0.jar
+=======
+ ext/okio-1.6.0.jar
+ release/modules/ext/okio-1.6.0.jar
+
+
+ ext/postgresql-42.3.5.jar
+ release/modules/ext/postgresql-42.3.5.jar
+>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
ext/Rejistry-1.1-SNAPSHOT.jar
- release\modules\ext\Rejistry-1.1-SNAPSHOT.jar
-
-
- ext/commons-beanutils-1.9.2.jar
- release\modules\ext\commons-beanutils-1.9.2.jar
-
-
- ext/batik-dom-1.6.jar
- release\modules\ext\batik-dom-1.6.jar
-
-
- ext/google-http-client-jackson2-1.29.0.jar
- release\modules\ext\google-http-client-jackson2-1.29.0.jar
-
-
- ext/threetenbp-1.3.3.jar
- release\modules\ext\threetenbp-1.3.3.jar
-
-
- ext/google-cloud-translate-1.70.0.jar
- release\modules\ext\google-cloud-translate-1.70.0.jar
-
-
- ext/grpc-stub-1.19.0.jar
- release\modules\ext\grpc-stub-1.19.0.jar
-
-
- ext/google-oauth-client-1.28.0.jar
- release\modules\ext\google-oauth-client-1.28.0.jar
+ release/modules/ext/Rejistry-1.1-SNAPSHOT.jar
ext/sevenzipjbinding-AllPlatforms.jar
- release\modules\ext\sevenzipjbinding-AllPlatforms.jar
+ release/modules/ext/sevenzipjbinding-AllPlatforms.jar
- ext/sleuthkit-4.10.1.jar
- release/modules/ext/sleuthkit-4.10.1.jar
+ ext/sevenzipjbinding.jar
+ release/modules/ext/sevenzipjbinding.jar
- ext/jutf7-1.0.0.jar
- release\modules\ext\jutf7-1.0.0.jar
+ ext/sleuthkit-4.11.1.jar
+ release/modules/ext/sleuthkit-4.11.1.jar
- ext/byte-buddy-agent-1.10.13.jar
- release\modules\ext\byte-buddy-agent-1.10.13.jar
+ ext/sleuthkit-caseuco-4.11.1.jar
+ release/modules/ext/sleuthkit-caseuco-4.11.1.jar
- ext/batik-awt-util-1.6.jar
- release\modules\ext\batik-awt-util-1.6.jar
+ ext/snakeyaml-1.30.jar
+ release/modules/ext/snakeyaml-1.30.jar
- ext/google-api-services-translate-v2-rev20170525-1.27.0.jar
- release\modules\ext\google-api-services-translate-v2-rev20170525-1.27.0.jar
+ ext/SparseBitSet-1.1.jar
+ release/modules/ext/SparseBitSet-1.1.jar
- ext/icepdf-viewer-6.2.2.jar
- release\modules\ext\icepdf-viewer-6.2.2.jar
+ ext/spotbugs-annotations-4.6.0.jar
+ release/modules/ext/spotbugs-annotations-4.6.0.jar
- ext/webp-imageio-sejda-0.1.0.jar
- release\modules\ext\webp-imageio-sejda-0.1.0.jar
+ ext/sqlite-jdbc-3.36.0.3.jar
+ release/modules/ext/sqlite-jdbc-3.36.0.3.jar
- ext/grpc-netty-shaded-1.19.0.jar
- release\modules\ext\grpc-netty-shaded-1.19.0.jar
+ ext/xmpcore-6.1.11.jar
+ release/modules/ext/xmpcore-6.1.11.jar
+
+
+ ext/YaraJNIWrapper.jar
+ release/modules/ext/YaraJNIWrapper.jar
+
+
+ ext/zookeeper-3.8.0.jar
+ release/modules/ext/zookeeper-3.8.0.jar
+
+
+ ext/zookeeper-jute-3.8.0.jar
+ release/modules/ext/zookeeper-jute-3.8.0.jar
diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java
index 26d1c7a9bc..79a0d715b2 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2019 Basis Technology Corp.
+ * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,6 +29,7 @@ import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.datamodel.BlackboardArtifactItem;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TagName;
@@ -46,6 +47,8 @@ import org.sleuthkit.datamodel.TskCoreException;
})
public class AddBlackboardArtifactTagAction extends AddTagAction {
+ private static final long serialVersionUID = 1L;
+
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
@@ -68,7 +71,7 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
"AddBlackboardArtifactTagAction.singularTagResult");
String pluralTagResult = NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.pluralTagResult");
- return Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class).size() > 1 ? pluralTagResult : singularTagResult;
+ return Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactItem.class).size() > 1 ? pluralTagResult : singularTagResult;
}
@Override
@@ -82,8 +85,14 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
* invocation of addTag(), we don't want to tag the same
* BlackboardArtifact more than once, so we dedupe the
* BlackboardArtifacts by stuffing them into a HashSet.
+ *
+ * RC (9/8/21): The documentation does NOT say that lookupAll() can
+ * return duplicates. That would be very broken. What motivated this
+ * "de-duping" ?
*/
- selectedArtifacts.addAll(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class));
+ for (BlackboardArtifactItem> item : Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactItem.class)) {
+ selectedArtifacts.add(item.getTskContent());
+ }
} else {
for (Content content : getContentToTag()) {
if (content instanceof BlackboardArtifact) {
@@ -111,4 +120,10 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
}
}).start();
}
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
}
diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java
index 9c059205f5..ff3dc08e04 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2013-2020 Basis Technology Corp.
+ * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -44,22 +44,29 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
- * An abstract base class for Actions that allow users to tag SleuthKit data
+ * An abstract super class for Actions that allow users to tag Sleuth Kit data
* model objects.
*/
abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
private static final long serialVersionUID = 1L;
private static final String NO_COMMENT = "";
- private final Collection content = new HashSet<>();
+ private final Collection contentObjsToTag;
+ /**
+ * Constructs an instance of an abstract super class for Actions that allow
+ * users to tag Sleuth Kit data model objects.
+ *
+ * @param menuText The menu item text.
+ */
AddTagAction(String menuText) {
super(menuText);
+ contentObjsToTag = new HashSet<>();
}
@Override
public JMenuItem getPopupPresenter() {
- content.clear();
+ contentObjsToTag.clear();
return new TagMenu();
}
@@ -70,7 +77,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
* @return The specified content for this action.
*/
Collection getContentToTag() {
- return Collections.unmodifiableCollection(content);
+ return Collections.unmodifiableCollection(contentObjsToTag);
}
/**
@@ -83,8 +90,8 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
* apply to the Content specified.
*/
public JMenuItem getMenuForContent(Collection extends Content> contentToTag) {
- content.clear();
- content.addAll(contentToTag);
+ contentObjsToTag.clear();
+ contentObjsToTag.addAll(contentToTag);
return new TagMenu();
}
@@ -111,6 +118,11 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
*/
abstract protected void addTag(TagName tagName, String comment);
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
/**
* Instances of this class implement a context menu user interface for
* creating or selecting a tag name for a tag and specifying an optional tag
@@ -126,7 +138,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
super(getActionDisplayName());
// Get the current set of tag names.
- Map tagNamesMap = null;
+ Map tagNamesMap;
List standardTagNames = TagsManager.getStandardTagNames();
Map tagSetMenuMap = new HashMap<>();
List standardTagMenuitems = new ArrayList<>();
@@ -240,5 +252,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
return tagNameItem;
}
+
}
+
}
diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties
index a2feedc54f..4ca72069dc 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties
@@ -45,3 +45,4 @@ OpenPythonModulesFolderAction.actionName.text=Python Plugins
OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0}
CTL_OpenPythonModulesFolderAction=Python Plugins
GetTagNameAndCommentDialog.tagCombo.toolTipText=Select tag to use
+CTL_ExitAction=Exit
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
index 507e079cad..5c9a0ea3ac 100755
--- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
@@ -96,3 +96,4 @@ OpenPythonModulesFolderAction.actionName.text=Python Plugins
OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0}
CTL_OpenPythonModulesFolderAction=Python Plugins
GetTagNameAndCommentDialog.tagCombo.toolTipText=Select tag to use
+CTL_ExitAction=Exit
diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle_ja.properties
index a4a460df69..037e719678 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/Bundle_ja.properties
+++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle_ja.properties
@@ -1,97 +1,83 @@
+#Thu Sep 30 10:26:59 UTC 2021
AddBlackboardArtifactTagAction.pluralTagResult=\u7d50\u679c\u30bf\u30b0\u3092\u8ffd\u52a0
AddBlackboardArtifactTagAction.singularTagResult=\u7d50\u679c\u30bf\u30b0\u3092\u8ffd\u52a0
AddBlackboardArtifactTagAction.taggingErr=\u30bf\u30b0\u4ed8\u3051\u30a8\u30e9\u30fc
-# {0} - artifactName
AddBlackboardArtifactTagAction.unableToTag.msg={0} \u3092\u30bf\u30b0\u4ed8\u3051\u3067\u304d\u307e\u305b\u3093\u3002
+AddBookmarkTagAction.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af
AddContentTagAction.cannotApplyTagErr=\u30bf\u30b0\u3092\u9069\u7528\u3067\u304d\u307e\u305b\u3093
AddContentTagAction.pluralTagFile=\u30d5\u30a1\u30a4\u30eb\u30bf\u30b0\u3092\u8ffd\u52a0
AddContentTagAction.singularTagFile=\u30d5\u30a1\u30a4\u30eb\u30bf\u30b0\u3092\u8ffd\u52a0
-# {0} - fileName
-# {1} - tagName
AddContentTagAction.tagExists={0} \u304c {1} \u3068\u3057\u3066\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u307e\u3057\u305f\u3002\u540c\u3058\u30bf\u30b0\u3092\u518d\u9069\u7528\u3067\u304d\u307e\u305b\u3093\u3002
AddContentTagAction.taggingErr=\u30bf\u30b0\u4ed8\u3051\u30a8\u30e9\u30fc
-# {0} - fileName
AddContentTagAction.unableToTag.msg={0} \u3092\u30bf\u30b0\u4ed8\u3051\u3067\u304d\u307e\u305b\u3093\u3002\u901a\u5e38\u306e\u30d5\u30a1\u30a4\u30eb\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
-# {0} - fileName
AddContentTagAction.unableToTag.msg2={0} \u3092\u30bf\u30b0\u4ed8\u3051\u3067\u304d\u307e\u305b\u3093\u3002
+AddTagAction.bookmarkFile=\u30d6\u30c3\u30af\u30de\u30fc\u30af\u30d5\u30a1\u30a4\u30eb
+AddTagAction.newTag=\u65b0\u898f\u30bf\u30b0...
+AddTagAction.noTags=\u30bf\u30b0\u306a\u3057
+AddTagAction.quickTag=\u30af\u30a4\u30c3\u30af\u30bf\u30b0
+AddTagAction.tagAndComment=\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8...
+CTL_DumpThreadAction=\u30b9\u30ec\u30c3\u30c9 \u30c0\u30f3\u30d7
+CTL_ExitAction=\u51fa\u53e3
+CTL_OpenLogFolder=\u30ed\u30b0\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
+CTL_OpenOutputFolder=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
+CTL_OpenPythonModulesFolderAction=Python\u30d7\u30e9\u30b0\u30a4\u30f3
CTL_ShowIngestProgressSnapshotAction=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b9\u30c6\u30fc\u30bf\u30b9\u8a73\u7d30
DeleteBlackboardArtifactTagAction.deleteTag=\u9078\u629e\u3057\u305f\u30bf\u30b0\u3092\u524a\u9664
DeleteBlackboardArtifactTagAction.tagDelErr=\u30bf\u30b0\u524a\u9664\u30a8\u30e9\u30fc
-# {0} - tagName
DeleteBlackboardArtifactTagAction.unableToDelTag.msg={0} \u3092Delete\u30bf\u30b0\u4ed8\u3051\u3067\u304d\u307e\u305b\u3093\u3002
DeleteContentTagAction.deleteTag=\u9078\u629e\u3057\u305f\u30bf\u30b0\u3092\u524a\u9664
DeleteContentTagAction.tagDelErr=\u30bf\u30b0\u524a\u9664\u30a8\u30e9\u30fc
-# {0} - tagName
DeleteContentTagAction.unableToDelTag.msg={0} \u3092Delete\u30bf\u30b0\u4ed8\u3051\u3067\u304d\u307e\u305b\u3093\u3002
DeleteFileBlackboardArtifactTagAction.deleteTag=\u7d50\u679c\u30bf\u30b0\u3092\u524a\u9664
-# {0} - artifactID
DeleteFileBlackboardArtifactTagAction.deleteTag.alert=\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c {0} \u3092\u30bf\u30b0\u306a\u3057\u306b\u3067\u304d\u307e\u305b\u3093\u3002
-# {0} - artifactID
DeleteFileBlackboardArtifactTagAction.deleteTags.alert=\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c {0} \u3092\u30bf\u30b0\u306a\u3057\u306b\u3067\u304d\u307e\u305b\u3093\u3002
DeleteFileContentTagAction.deleteTag=\u30d5\u30a1\u30a4\u30eb\u30bf\u30b0\u3092\u524a\u9664
-# {0} - fileID
DeleteFileContentTagAction.deleteTag.alert=\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c {0} \u3092\u30bf\u30b0\u306a\u3057\u306b\u3067\u304d\u307e\u305b\u3093\u3002
ExitAction.confirmationDialog.message=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u5b9f\u884c\u4e2d\u3067\u3059\u3002\u7d42\u4e86\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
ExitAction.confirmationDialog.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u5b9f\u884c\u4e2d\u3067\u3059
-# {0} - \u4f8b\u5916\u30e1\u30c3\u30bb\u30fc\u30b8
-ExitAction.messageBox.caseCloseExceptionMessage=\u6b21\u306e\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u3044\u308b\u9593\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: {0}
-GetTagNameDialog.descriptionLabel.text=\u8a18\u8ff0:
+ExitAction.messageBox.caseCloseExceptionMessage=\u6b21\u306e\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u3044\u308b\u9593\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0}
+GetTagNameAndCommentDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
+GetTagNameAndCommentDialog.cancelName=\u53d6\u308a\u6d88\u3057
+GetTagNameAndCommentDialog.commentLabel.text=\u30b3\u30e1\u30f3\u30c8\:
+GetTagNameAndCommentDialog.commentText.text=
+GetTagNameAndCommentDialog.commentText.toolTipText=\u4efb\u610f\u30bf\u30b0\u306e\u30b3\u30e1\u30f3\u30c8\u3092\u5165\u529b\u3059\u308b\u304b\u7a7a\u6b04\u306e\u307e\u307e\u306b\u3059\u308b
+GetTagNameAndCommentDialog.newTagButton.text=\u65b0\u898f\u30bf\u30b0
+GetTagNameAndCommentDialog.noTags=\u30bf\u30b0\u306a\u3057
+GetTagNameAndCommentDialog.okButton.text=OK
+GetTagNameAndCommentDialog.selectTag=\u30bf\u30b0\u3092\u9078\u629e
+GetTagNameAndCommentDialog.tagCombo.toolTipText=\u4f7f\u7528\u3059\u308b\u30bf\u30b0\u3092\u9078\u629e
+GetTagNameAndCommentDialog.tagLabel.text=\u30bf\u30b0\:
+GetTagNameDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
+GetTagNameDialog.cancelName=\u53d6\u308a\u6d88\u3057
+GetTagNameDialog.createTag=\u30bf\u30b0\u3092\u4f5c\u6210
+GetTagNameDialog.descriptionLabel.text=\u8a18\u8ff0\:
+GetTagNameDialog.dupTagErr=\u30bf\u30b0\u8907\u88fd\u30a8\u30e9\u30fc
+GetTagNameDialog.illegalChars.msg=\u30bf\u30b0\u540d\u306b\u4e0d\u6b63\u306a\u6587\u5b57\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002\n\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u3089\u308c\u307e\u305b\u3093\: \\ \: * ? " < > | , ;
+GetTagNameDialog.illegalCharsErr=\u4e0d\u6b63\u306a\u6587\u5b57
+GetTagNameDialog.mustSupplyTtagName.msg=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30bf\u30b0\u540d\u3092\u63d0\u4f9b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
+GetTagNameDialog.newTagPanel.border.title=\u65b0\u898f\u30bf\u30b0
GetTagNameDialog.notableCheckbox.text=\u30bf\u30b0\u306f\u9805\u76ee\u304c\u9855\u8457\u3067\u3042\u308b\u3068\u793a\u5506\u3057\u3066\u3044\u307e\u3059\u3002
+GetTagNameDialog.okButton.text=OK
+GetTagNameDialog.preexistingLabel.text=\u524d\u304b\u3089\u5b58\u5728\u3059\u308b\u30bf\u30b0\u540d\:
GetTagNameDialog.tagDescriptionIllegalCharacters.message=\u30bf\u30b0\u306e\u8a18\u8ff0\u306b\u30ab\u30f3\u30de(,)\u3084\u30bb\u30df\u30b3\u30ed\u30f3(;)\u3092\u542b\u3081\u3089\u308c\u307e\u305b\u3093
GetTagNameDialog.tagDescriptionIllegalCharacters.title=\u30bf\u30b0\u306e\u8a18\u8ff0\u306b\u7121\u52b9\u306a\u6587\u5b57\u304c\u3042\u308a\u307e\u3059
+GetTagNameDialog.tagNameAlreadyDef.msg={0} \u30bf\u30b0\u540d\u3092\u3059\u3067\u306b\u5b9a\u7fa9\u6e08\u307f\u3067\u3059\u3002
GetTagNameDialog.tagNameAlreadyExists.message=\u30bf\u30b0\u540d\u306f\u4e00\u610f\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002\u3053\u306e\u540d\u524d\u306e\u30bf\u30b0\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\u3002
GetTagNameDialog.tagNameAlreadyExists.title=\u30bf\u30b0\u540d\u3092\u8907\u88fd
-GetTagNameDialog.tagNameField.text=
-GetTagNameDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
-GetTagNameDialog.okButton.text=OK
-GetTagNameDialog.preexistingLabel.text=\u524d\u304b\u3089\u5b58\u5728\u3059\u308b\u30bf\u30b0\u540d:
-GetTagNameDialog.newTagPanel.border.title=\u65b0\u898f\u30bf\u30b0
-GetTagNameDialog.tagNameLabel.text=\u30bf\u30b0\u540d:
-GetTagNameAndCommentDialog.newTagButton.text=\u65b0\u898f\u30bf\u30b0
-GetTagNameAndCommentDialog.okButton.text=OK
-GetTagNameAndCommentDialog.commentText.toolTipText=\u4efb\u610f\u30bf\u30b0\u306e\u30b3\u30e1\u30f3\u30c8\u3092\u5165\u529b\u3059\u308b\u304b\u7a7a\u6b04\u306e\u307e\u307e\u306b\u3059\u308b
-GetTagNameAndCommentDialog.commentText.text=
-GetTagNameAndCommentDialog.commentLabel.text=\u30b3\u30e1\u30f3\u30c8:
-# \u3053\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u3001[\u30c4\u30fc\u30eb | \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8] \u3092\u9078\u629e\u3057\u3001
-# \u30a8\u30c7\u30a3\u30bf\u30fc\u3067\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u958b\u304d\u307e\u3059\u3002
-GetTagNameAndCommentDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
-GetTagNameAndCommentDialog.tagLabel.text=\u30bf\u30b0:
-AddTagAction.bookmarkFile=\u30d6\u30c3\u30af\u30de\u30fc\u30af\u30d5\u30a1\u30a4\u30eb
-AddTagAction.quickTag=\u30af\u30a4\u30c3\u30af\u30bf\u30b0
-AddTagAction.noTags=\u30bf\u30b0\u306a\u3057
-AddTagAction.newTag=\u65b0\u898f\u30bf\u30b0...
-AddTagAction.tagAndComment=\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8...
-AddBookmarkTagAction.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af
-GetTagNameAndCommentDialog.noTags=\u30bf\u30b0\u306a\u3057
-GetTagNameAndCommentDialog.selectTag=\u30bf\u30b0\u3092\u9078\u629e
-GetTagNameAndCommentDialog.cancelName=\u53d6\u308a\u6d88\u3057
-GetTagNameDialog.createTag=\u30bf\u30b0\u3092\u4f5c\u6210
-GetTagNameDialog.cancelName=\u53d6\u308a\u6d88\u3057
-GetTagNameDialog.mustSupplyTtagName.msg=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30bf\u30b0\u540d\u3092\u63d0\u4f9b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
GetTagNameDialog.tagNameErr=\u30bf\u30b0\u540d
-GetTagNameDialog.illegalChars.msg=\u30bf\u30b0\u540d\u306b\u4e0d\u6b63\u306a\u6587\u5b57\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002\n\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u3089\u308c\u307e\u305b\u3093: \\ : * ? " < > | , ;
-GetTagNameDialog.illegalCharsErr=\u4e0d\u6b63\u306a\u6587\u5b57
-GetTagNameDialog.unableToAddTagNameToCase.msg={0} \u30bf\u30b0\u540d\u3092\u30b1\u30fc\u30b9\u306b\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002
-GetTagNameDialog.taggingErr=\u30bf\u30b0\u4ed8\u3051\u30a8\u30e9\u30fc
-GetTagNameDialog.tagNameAlreadyDef.msg={0} \u30bf\u30b0\u540d\u3092\u3059\u3067\u306b\u5b9a\u7fa9\u6e08\u307f\u3067\u3059\u3002
-GetTagNameDialog.dupTagErr=\u30bf\u30b0\u8907\u88fd\u30a8\u30e9\u30fc
GetTagNameDialog.tagNameExistsTskCore.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u306b {0} \u30bf\u30b0\u540d\u304c\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\u304c\u3001\u691c\u7d22\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
-OpenLogFolder.error1=\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093: {0}
+GetTagNameDialog.tagNameField.text=
+GetTagNameDialog.tagNameLabel.text=\u30bf\u30b0\u540d\:
+GetTagNameDialog.taggingErr=\u30bf\u30b0\u4ed8\u3051\u30a8\u30e9\u30fc
+GetTagNameDialog.unableToAddTagNameToCase.msg={0} \u30bf\u30b0\u540d\u3092\u30b1\u30fc\u30b9\u306b\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002
OpenLogFolder.CouldNotOpenLogFolder=\u30ed\u30b0\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
-CTL_OpenLogFolder=\u30ed\u30b0\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
-CTL_OpenOutputFolder=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
-OpenOutputFolder.error1=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093: {0}
-OpenOutputFolder.noCaseOpen=\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u306a\u3044\u305f\u3081\u3001\u73fe\u5728\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
+OpenLogFolder.error1=\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\: {0}
OpenOutputFolder.CouldNotOpenOutputFolder=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
-# {0} - \u53e4\u3044\u30bf\u30b0\u540d
-# {1} - artifactID
+OpenOutputFolder.error1=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\: {0}
+OpenOutputFolder.noCaseOpen=\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u306a\u3044\u305f\u3081\u3001\u73fe\u5728\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
+OpenPythonModulesFolderAction.actionName.text=Python\u30d7\u30e9\u30b0\u30a4\u30f3
+OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python\u30d7\u30e9\u30b0\u30a4\u30f3\u30d5\u30a9\u30eb\u30c0\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\: {0}
ReplaceBlackboardArtifactTagAction.replaceTag.alert=\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c {1} \u306e\u30bf\u30b0 {0} \u3092\u7f6e\u63db\u3067\u304d\u307e\u305b\u3093\u3002
-# {0} - \u53e4\u3044\u30bf\u30b0\u540d
-# {1} - \u30b3\u30f3\u30c6\u30f3\u30c4\u30aa\u30d6\u30b8\u30a7\u30af\u30c8ID
ReplaceContentTagAction.replaceTag.alert={1} \u306e\u30bf\u30b0 {0} \u3092\u7f6e\u63db\u3067\u304d\u307e\u305b\u3093\u3002
ReplaceTagAction.replaceTag=\u3067\u9078\u629e\u3057\u305f\u30bf\u30b0\u3092\u7f6e\u63db
ShowIngestProgressSnapshotAction.actionName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u9032\u884c\u72b6\u6cc1\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u53d6\u5f97
-OpenPythonModulesFolderAction.actionName.text=Python\u30d7\u30e9\u30b0\u30a4\u30f3
-OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python\u30d7\u30e9\u30b0\u30a4\u30f3\u30d5\u30a9\u30eb\u30c0\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093: {0}
-CTL_OpenPythonModulesFolderAction=Python\u30d7\u30e9\u30b0\u30a4\u30f3
-GetTagNameAndCommentDialog.tagCombo.toolTipText=\u4f7f\u7528\u3059\u308b\u30bf\u30b0\u3092\u9078\u629e
diff --git a/Core/src/org/sleuthkit/autopsy/actions/DeleteFileBlackboardArtifactTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/DeleteFileBlackboardArtifactTagAction.java
index 8c7c77652e..70b037e017 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/DeleteFileBlackboardArtifactTagAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/DeleteFileBlackboardArtifactTagAction.java
@@ -21,12 +21,12 @@ package org.sleuthkit.autopsy.actions;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
+import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javax.swing.AbstractAction;
@@ -40,6 +40,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.datamodel.BlackboardArtifactItem;
import org.sleuthkit.autopsy.tags.TagUtils;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
@@ -158,7 +159,11 @@ public class DeleteFileBlackboardArtifactTagAction extends AbstractAction implem
private static final long serialVersionUID = 1L;
TagMenu() {
- this(new HashSet<>(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class)));
+ this(Utilities.actionsGlobalContext()
+ .lookupAll(BlackboardArtifactItem.class)
+ .stream()
+ .map((bai) -> (BlackboardArtifact) bai.getTskContent())
+ .collect(Collectors.toSet()));
}
TagMenu(Collection selectedBlackboardArtifactsList) {
diff --git a/Core/src/org/sleuthkit/autopsy/actions/ExitAction.java b/Core/src/org/sleuthkit/autopsy/actions/ExitAction.java
index 7240afca92..31162cc67b 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/ExitAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/ExitAction.java
@@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
* The action associated with the Case/Exit menu item. It closes the current
* case, if any, and shuts down the application.
*/
-@ActionRegistration(displayName = "Exit", iconInMenu = true)
+@ActionRegistration(displayName = "#CTL_ExitAction", iconInMenu = true)
@ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999)
@ActionID(id = "org.sleuthkit.autopsy.casemodule.ExitAction", category = "Case")
final public class ExitAction implements ActionListener {
diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java
index f82a30c05a..2617d08df3 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java
@@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.actions;
+import java.awt.Cursor;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -25,6 +26,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
@@ -33,6 +35,7 @@ import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
+import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
@@ -163,7 +166,50 @@ public class GetTagNameDialog extends JDialog {
return tagDisplayNames.get(rowIndex);
}
}
+
+ /**
+ * A SwingWorker for creating a new TagName.
+ */
+ private class AddTagNameWorker extends SwingWorker {
+ private final String name;
+ private final String description;
+ private final TskData.FileKnown status;
+ private final TagName.HTML_COLOR color;
+
+ AddTagNameWorker(String name, String description, TskData.FileKnown status, TagName.HTML_COLOR color) {
+ this.name = name;
+ this.description = description;
+ this.status = status;
+ this.color = color;
+ }
+
+ @Override
+ protected TagName doInBackground() throws Exception {
+ return Case.getCurrentCaseThrows().getServices().getTagsManager().addTagName(name, description, color, status);
+ }
+
+ @Override
+ protected void done() {
+ try {
+ tagName = get();
+ dispose();
+ } catch (ExecutionException | InterruptedException ex) {
+ Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + name + " tag name", ex); //NON-NLS
+ JOptionPane.showMessageDialog(GetTagNameDialog.this,
+ NbBundle.getMessage(GetTagNameDialog.this.getClass(),
+ "GetTagNameDialog.unableToAddTagNameToCase.msg",
+ name),
+ NbBundle.getMessage(this.getClass(), "GetTagNameDialog.taggingErr"),
+ JOptionPane.ERROR_MESSAGE);
+ tagName = null;
+ }
+
+ okButton.setEnabled(true);
+ cancelButton.setEnabled(true);
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }
/**
* 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
@@ -351,32 +397,12 @@ public class GetTagNameDialog extends JDialog {
tagName = tagNamesMap.get(tagDisplayName);
if (tagName == null) {
- try {
- tagName = Case.getCurrentCaseThrows().getServices().getTagsManager().addTagName(tagDisplayName, userTagDescription, TagName.HTML_COLOR.NONE, status);
- dispose();
- } catch (TskCoreException | NoCurrentCaseException ex) {
- Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS
- JOptionPane.showMessageDialog(this,
- NbBundle.getMessage(this.getClass(),
- "GetTagNameDialog.unableToAddTagNameToCase.msg",
- tagDisplayName),
- NbBundle.getMessage(this.getClass(), "GetTagNameDialog.taggingErr"),
- JOptionPane.ERROR_MESSAGE);
- tagName = null;
- } catch (TagsManager.TagNameAlreadyExistsException ex) {
- try {
- tagName = Case.getCurrentCaseThrows().getServices().getTagsManager().getDisplayNamesToTagNamesMap().get(tagDisplayName);
- } catch (TskCoreException | NoCurrentCaseException ex1) {
- Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, tagDisplayName + " exists in database but an error occurred in retrieving it.", ex1); //NON-NLS
- JOptionPane.showMessageDialog(this,
- NbBundle.getMessage(this.getClass(),
- "GetTagNameDialog.tagNameExistsTskCore.msg",
- tagDisplayName),
- NbBundle.getMessage(this.getClass(), "GetTagNameDialog.dupTagErr"),
- JOptionPane.ERROR_MESSAGE);
- tagName = null;
- }
- }
+ AddTagNameWorker worker = new AddTagNameWorker(tagDisplayName, userTagDescription, status, TagName.HTML_COLOR.NONE );
+ okButton.setEnabled(false);
+ cancelButton.setEnabled(false);
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ worker.execute();
} else {
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameAlreadyExists.message"),
diff --git a/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java b/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java
index d74511996c..dad577e8cb 100755
--- a/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2020 Basis Technology Corp.
+ * Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,18 +24,10 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
-import java.util.stream.Collectors;
import javax.swing.SwingWorker;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
@@ -46,6 +38,8 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+import org.sleuthkit.autopsy.coreutils.ThreadUtils;
+import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
/**
* Action class for the Thread Dump help menu item. If there is no case open the
@@ -63,8 +57,6 @@ public final class ThreadDumpAction extends CallableSystemAction implements Acti
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(ThreadDumpAction.class.getName());
- private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss-SSSS");
-
@Override
public void performAction() {
(new ThreadDumper()).run();
@@ -114,26 +106,13 @@ public final class ThreadDumpAction extends CallableSystemAction implements Acti
* @throws IOException
*/
private File createThreadDump() throws IOException {
+
+ // generate thread dump
+ String threadDump = ThreadUtils.generateThreadDump();
+
File dumpFile = createFilePath().toFile();
try (BufferedWriter writer = new BufferedWriter(new FileWriter(dumpFile, true))) {
- ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
- ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100);
- for (ThreadInfo threadInfo : threadInfos) {
- writer.write(threadInfo.toString());
- writer.write("\n");
- }
-
- long[] deadlockThreadIds = threadMXBean.findDeadlockedThreads();
- if (deadlockThreadIds != null) {
- writer.write("-------------------List of Deadlocked Thread IDs ---------------------");
- String idsList = (Arrays
- .stream(deadlockThreadIds)
- .boxed()
- .collect(Collectors.toList()))
- .stream().map(n -> String.valueOf(n))
- .collect(Collectors.joining("-", "{", "}"));
- writer.write(idsList);
- }
+ writer.write(threadDump);
}
return dumpFile;
@@ -145,7 +124,7 @@ public final class ThreadDumpAction extends CallableSystemAction implements Acti
* @return Path for dump file.
*/
private Path createFilePath() {
- String fileName = "ThreadDump_" + DATE_FORMAT.format(new Date()) + ".txt";
+ String fileName = "ThreadDump_" + TimeStampUtils.createTimeStamp() + ".txt";
if (Case.isCaseOpen()) {
return Paths.get(Case.getCurrentCase().getLogDirectoryPath(), fileName);
}
diff --git a/Core/src/org/sleuthkit/autopsy/actions/ViewArtifactAction.java b/Core/src/org/sleuthkit/autopsy/actions/ViewArtifactAction.java
new file mode 100644
index 0000000000..6da2b55862
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/actions/ViewArtifactAction.java
@@ -0,0 +1,76 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2021 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.actions;
+
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+import javax.swing.AbstractAction;
+import javax.swing.SwingWorker;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
+import org.sleuthkit.datamodel.BlackboardArtifact;
+
+/**
+ * An action that navigates to an artifact.
+ */
+public class ViewArtifactAction extends AbstractAction {
+
+ private static final Logger logger = Logger.getLogger(ViewArtifactAction.class.getName());
+ private final BlackboardArtifact artifact;
+
+ /**
+ * Main constructor.
+ *
+ * @param artifact The artifact to navigate to in the action.
+ * @param displayName The display name of the menu item.
+ */
+ public ViewArtifactAction(BlackboardArtifact artifact, String displayName) {
+ super(displayName);
+ this.artifact = artifact;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ new SwingWorker() {
+
+ @Override
+ protected Void doInBackground() throws Exception {
+ DirectoryTreeTopComponent.findInstance().viewArtifact(artifact);
+ return null;
+ }
+
+ @Override
+ protected void done() {
+ try {
+ get();
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, "Unexpected interrupt while navigating to artifact.", ex);
+ } catch (ExecutionException ex) {
+ logger.log(Level.SEVERE, "Error navigating to artifact.", ex);
+ }
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }.execute();
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java b/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java
new file mode 100644
index 0000000000..200759fbf5
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java
@@ -0,0 +1,77 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2021 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.actions;
+
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+import javax.swing.AbstractAction;
+import javax.swing.SwingWorker;
+import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
+import org.sleuthkit.datamodel.OsAccount;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.coreutils.Logger;
+
+/**
+ * An action that navigates to an os account.
+ */
+public class ViewOsAccountAction extends AbstractAction {
+
+ private static final Logger logger = Logger.getLogger(ViewOsAccountAction.class.getName());
+
+ private final OsAccount osAccount;
+
+ /**
+ * Main constructor.
+ *
+ * @param osAccount The os account to navigate to in the action.
+ * @param displayName The display name of the menu item.
+ */
+ public ViewOsAccountAction(OsAccount osAccount, String displayName) {
+ super(displayName);
+ this.osAccount = osAccount;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ new SwingWorker() {
+
+ @Override
+ protected Void doInBackground() throws Exception {
+ DirectoryTreeTopComponent.findInstance().viewOsAccount(osAccount);
+ return null;
+ }
+
+ @Override
+ protected void done() {
+ try {
+ get();
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, "Unexpected interrupt while navigating to OS Account.", ex);
+ } catch (ExecutionException ex) {
+ logger.log(Level.SEVERE, "Error navigating to OS Account.", ex);
+ }
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }.execute();
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchAction.java b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchAction.java
index 676a565de2..b4689db917 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchAction.java
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchAction.java
@@ -32,9 +32,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
* Action for accessing the Search Other Cases dialog.
*/
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.allcasessearch.AllCasesSearchAction")
-@ActionRegistration(displayName = "#CTL_OtherCasesSearchAction=Search All Cases", lazy = false)
+@ActionRegistration(displayName = "#CTL_OtherCasesSearchAction=Search Central Repository", lazy = false)
@ActionReference(path = "Menu/Tools", position = 201)
-@NbBundle.Messages({"CTL_AllCasesSearchAction=Search All Cases"})
+@NbBundle.Messages({"CTL_AllCasesSearchAction=Search Central Repository"})
public class AllCasesSearchAction extends CallableSystemAction {
@Override
@@ -54,7 +54,7 @@ public class AllCasesSearchAction extends CallableSystemAction {
}
@NbBundle.Messages({
- "AllCasesSearchAction.getName.text=Search All Cases"})
+ "AllCasesSearchAction.getName.text=Search Central Repository"})
@Override
public String getName() {
return Bundle.AllCasesSearchAction_getName_text();
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.form b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.form
index f378613c11..aca01ada64 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.form
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.form
@@ -24,10 +24,15 @@
-
+
-
+
+
+
+
+
+
@@ -35,16 +40,23 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
@@ -60,17 +72,19 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
@@ -85,16 +99,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -158,5 +162,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.java b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.java
index d8c82dc40b..077e642b42 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.java
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/AllCasesSearchDialog.java
@@ -21,8 +21,10 @@ package org.sleuthkit.autopsy.allcasessearch;
import java.awt.Color;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
@@ -30,6 +32,7 @@ import javax.swing.JFrame;
import javax.swing.SwingWorker;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
+import org.apache.commons.lang3.StringUtils;
import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;
@@ -48,9 +51,9 @@ import org.sleuthkit.autopsy.datamodel.EmptyNode;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
@Messages({
- "AllCasesSearchDialog.dialogTitle.text=Search All Cases",
+ "AllCasesSearchDialog.dialogTitle.text=Search Central Repository",
"AllCasesSearchDialog.resultsTitle.text=All Cases",
- "AllCasesSearchDialog.resultsDescription.text=All Cases Search",
+ "AllCasesSearchDialog.resultsDescription.text=Search Central Repository",
"AllCasesSearchDialog.emptyNode.text=No results found.",
"AllCasesSearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash.",
"AllCasesSearchDialog.validation.invalidEmail=The supplied value is not a valid e-mail address.",
@@ -63,14 +66,14 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
"AllCasesSearchDialog.validation.invalidIccid=The supplied value is not a valid ICCID number.",
"AllCasesSearchDialog.validation.genericMessage=The supplied value is not valid.",
"# {0} - number of cases",
- "AllCasesSearchDialog.caseLabel.text=The current Central Repository contains {0} case(s)."
+ "AllCasesSearchDialog.caseLabel.text=The Central Repository contains {0} case(s)."
})
/**
* The Search All Cases dialog allows users to search for specific types of
* correlation properties in the Central Repository.
*/
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
-final class AllCasesSearchDialog extends javax.swing.JDialog {
+ final class AllCasesSearchDialog extends javax.swing.JDialog {
private static final Logger logger = Logger.getLogger(AllCasesSearchDialog.class.getName());
private static final long serialVersionUID = 1L;
@@ -95,19 +98,21 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
* @param type The correlation type.
* @param value The value to be matched.
*/
- private void search(CorrelationAttributeInstance.Type type, String value) {
+ private void search(CorrelationAttributeInstance.Type type, String[] values) {
new SwingWorker, Void>() {
@Override
protected List doInBackground() {
List correlationInstances = new ArrayList<>();
- try {
- correlationInstances = CentralRepository.getInstance().getArtifactInstancesByTypeValue(type, value);
- } catch (CentralRepoException ex) {
- logger.log(Level.SEVERE, "Unable to connect to the Central Repository database.", ex);
- } catch (CorrelationAttributeNormalizationException ex) {
- logger.log(Level.SEVERE, "Unable to retrieve data from the Central Repository.", ex);
+ for (String value : values) {
+ try {
+ correlationInstances.addAll(CentralRepository.getInstance().getArtifactInstancesByTypeValue(type, value));
+ } catch (CentralRepoException ex) {
+ logger.log(Level.SEVERE, "Unable to connect to the Central Repository database.", ex);
+ } catch (CorrelationAttributeNormalizationException ex) {
+ logger.log(Level.WARNING, "Unable to retrieve data from the Central Repository.", ex);
+ }
}
return correlationInstances;
@@ -125,8 +130,8 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
AllCasesSearchNode searchNode = new AllCasesSearchNode(correlationInstances);
TableFilterNode tableFilterNode = new TableFilterNode(searchNode, true, searchNode.getName());
- String resultsText = String.format("%s (%s; \"%s\")",
- Bundle.AllCasesSearchDialog_resultsTitle_text(), type.getDisplayName(), value);
+ String resultsText = String.format("%s (%s)",
+ Bundle.AllCasesSearchDialog_resultsTitle_text(), type.getDisplayName());
final TopComponent searchResultWin;
if (correlationInstances.isEmpty()) {
Node emptyNode = new TableFilterNode(
@@ -155,26 +160,21 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
private void initComponents() {
correlationValueLabel = new javax.swing.JLabel();
- correlationValueTextField = new javax.swing.JTextField();
searchButton = new javax.swing.JButton();
correlationTypeComboBox = new javax.swing.JComboBox<>();
correlationTypeLabel = new javax.swing.JLabel();
errorLabel = new javax.swing.JLabel();
descriptionLabel = new javax.swing.JLabel();
casesLabel = new javax.swing.JLabel();
+ correlationValueScrollPane = new javax.swing.JScrollPane();
+ correlationValueTextArea = new javax.swing.JTextArea();
+ normalizedLabel = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setResizable(false);
org.openide.awt.Mnemonics.setLocalizedText(correlationValueLabel, org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.correlationValueLabel.text")); // NOI18N
- correlationValueTextField.setText(org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.correlationValueTextField.text")); // NOI18N
- correlationValueTextField.addKeyListener(new java.awt.event.KeyAdapter() {
- public void keyReleased(java.awt.event.KeyEvent evt) {
- valueFieldKeyReleaseListener(evt);
- }
- });
-
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.searchButton.text")); // NOI18N
searchButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -198,6 +198,13 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
casesLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
org.openide.awt.Mnemonics.setLocalizedText(casesLabel, org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.casesLabel.text")); // NOI18N
+ correlationValueTextArea.setColumns(20);
+ correlationValueTextArea.setRows(5);
+ correlationValueTextArea.setText(org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.correlationValueTextArea.text")); // NOI18N
+ correlationValueScrollPane.setViewportView(correlationValueTextArea);
+
+ org.openide.awt.Mnemonics.setLocalizedText(normalizedLabel, org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, "AllCasesSearchDialog.normalizedLabel.text")); // NOI18N
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@@ -205,20 +212,28 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(descriptionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
+ .addComponent(descriptionLabel)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(casesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(searchButton))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(correlationValueLabel)
.addComponent(correlationTypeLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(correlationTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(correlationValueTextField)
- .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(casesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGap(18, 18, 18)
- .addComponent(searchButton)))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(normalizedLabel)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(correlationTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(correlationValueScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 379, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addGap(142, 142, 142))
+ .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap())
);
layout.setVerticalGroup(
@@ -230,16 +245,18 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(correlationTypeLabel))
- .addGap(15, 15, 15)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(correlationValueTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(correlationValueLabel))
+ .addGap(18, 18, 18)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(correlationValueLabel)
+ .addComponent(correlationValueScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(normalizedLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
.addComponent(errorLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(searchButton)
- .addComponent(casesLabel))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(casesLabel, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(searchButton, javax.swing.GroupLayout.Alignment.TRAILING))
.addContainerGap())
);
@@ -251,50 +268,55 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
CorrelationAttributeInstance.Type correlationType = selectedCorrelationType;
- String correlationValue = correlationValueTextField.getText().trim();
+ String correlationValue = correlationValueTextArea.getText().trim();
- if (validateInputs(correlationType, correlationValue)) {
- search(correlationType, correlationValue);
- dispose();
- } else {
- String validationMessage;
- switch (correlationType.getId()) {
- case CorrelationAttributeInstance.FILES_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidHash();
- break;
- case CorrelationAttributeInstance.DOMAIN_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidDomain();
- break;
- case CorrelationAttributeInstance.EMAIL_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidEmail();
- break;
- case CorrelationAttributeInstance.PHONE_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidPhone();
- break;
- case CorrelationAttributeInstance.SSID_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidSsid();
- break;
- case CorrelationAttributeInstance.MAC_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidMac();
- break;
- case CorrelationAttributeInstance.IMEI_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImei();
- break;
- case CorrelationAttributeInstance.IMSI_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImsi();
- break;
- case CorrelationAttributeInstance.ICCID_TYPE_ID:
- validationMessage = Bundle.AllCasesSearchDialog_validation_invalidIccid();
- break;
- default:
- validationMessage = Bundle.AllCasesSearchDialog_validation_genericMessage();
- break;
+ String[] correlationValueLines = correlationValue.split("\r\n|\n|\r");
+// for (String correlationValueLine : lines) {
+
+ if (validateInputs(correlationType, correlationValueLines)) {
+ search(correlationType, correlationValueLines);
+ dispose();
+ } else {
+ String validationMessage;
+ switch (correlationType.getId()) {
+ case CorrelationAttributeInstance.FILES_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidHash();
+ break;
+ case CorrelationAttributeInstance.DOMAIN_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidDomain();
+ break;
+ case CorrelationAttributeInstance.EMAIL_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidEmail();
+ break;
+ case CorrelationAttributeInstance.PHONE_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidPhone();
+ break;
+ case CorrelationAttributeInstance.SSID_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidSsid();
+ break;
+ case CorrelationAttributeInstance.MAC_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidMac();
+ break;
+ case CorrelationAttributeInstance.IMEI_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImei();
+ break;
+ case CorrelationAttributeInstance.IMSI_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImsi();
+ break;
+ case CorrelationAttributeInstance.ICCID_TYPE_ID:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_invalidIccid();
+ break;
+ default:
+ validationMessage = Bundle.AllCasesSearchDialog_validation_genericMessage();
+ break;
+ }
+
+ errorLabel.setText(validationMessage);
+ searchButton.setEnabled(false);
+ correlationValueTextArea.grabFocus();
}
- errorLabel.setText(validationMessage);
- searchButton.setEnabled(false);
- correlationValueTextField.grabFocus();
- }
+ // }
}//GEN-LAST:event_searchButtonActionPerformed
private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed
@@ -302,11 +324,6 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
errorLabel.setText("");
}//GEN-LAST:event_correlationTypeComboBoxActionPerformed
- private void valueFieldKeyReleaseListener(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_valueFieldKeyReleaseListener
- //make error message go away when the user enters anything in the value field
- errorLabel.setText("");
- }//GEN-LAST:event_valueFieldKeyReleaseListener
-
/**
* Validate the supplied input.
*
@@ -315,10 +332,12 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
*
* @return True if the input is valid for the given type; otherwise false.
*/
- private boolean validateInputs(CorrelationAttributeInstance.Type type, String value) {
+ private boolean validateInputs(CorrelationAttributeInstance.Type type, String[] values) {
try {
- CorrelationAttributeNormalizer.normalize(type, value);
- } catch (CorrelationAttributeNormalizationException ex) {
+ for (String value : values) {
+ CorrelationAttributeNormalizer.normalize(type, value);
+ }
+ } catch (CorrelationAttributeNormalizationException | CentralRepoException ex) {
// No need to log this.
return false;
}
@@ -339,15 +358,33 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
CentralRepository dbManager = CentralRepository.getInstance();
correlationTypes.clear();
correlationTypes.addAll(dbManager.getDefinedCorrelationTypes());
+// correlationTypes.addAll(java.util.Collections.sort(dbManager.getDefinedCorrelationTypes(), Collator.getInstance()));
int numberOfCases = dbManager.getCases().size();
casesLabel.setText(Bundle.AllCasesSearchDialog_caseLabel_text(numberOfCases));
} catch (CentralRepoException ex) {
logger.log(Level.SEVERE, "Unable to connect to the Central Repository database.", ex);
}
+ List displayNames = new ArrayList<>();
for (CorrelationAttributeInstance.Type type : correlationTypes) {
- correlationTypeComboBox.addItem(type.getDisplayName());
+ String displayName = type.getDisplayName();
+ if (displayName.toLowerCase().contains("addresses")) {
+ type.setDisplayName(displayName.replace("Addresses", "Address"));
+ } else if (displayName.toLowerCase().equals("files")) {
+ type.setDisplayName("File MD5");
+ } else if (displayName.toLowerCase().endsWith("s") && !displayName.toLowerCase().endsWith("address")) {
+ type.setDisplayName(StringUtils.substring(displayName, 0, displayName.length() - 1));
+ } else {
+ type.setDisplayName(displayName);
+ }
+
+ displayNames.add(type.getDisplayName());
}
+ Collections.sort(displayNames);
+ for (String displayName : displayNames) {
+ correlationTypeComboBox.addItem(displayName);
+ }
+
correlationTypeComboBox.setSelectedIndex(0);
correlationTypeComboBox.addItemListener(new ItemListener() {
@@ -364,7 +401,7 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
/*
* Create listener for text input.
*/
- correlationValueTextField.getDocument().addDocumentListener(new DocumentListener() {
+ correlationValueTextArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
updateSearchButton();
@@ -440,7 +477,7 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
text = "";
break;
}
- correlationValueTextFieldPrompt = new TextPrompt(text, correlationValueTextField);
+ correlationValueTextFieldPrompt = new TextPrompt(text, correlationValueTextArea);
/**
* Sets the foreground color and transparency of the text prompt.
@@ -470,7 +507,7 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
* been provided for the correlation property value.
*/
private void updateSearchButton() {
- searchButton.setEnabled(correlationValueTextField.getText().isEmpty() == false);
+ searchButton.setEnabled(correlationValueTextArea.getText().isEmpty() == false);
}
/**
@@ -486,9 +523,11 @@ final class AllCasesSearchDialog extends javax.swing.JDialog {
private javax.swing.JComboBox correlationTypeComboBox;
private javax.swing.JLabel correlationTypeLabel;
private javax.swing.JLabel correlationValueLabel;
- private javax.swing.JTextField correlationValueTextField;
+ private javax.swing.JScrollPane correlationValueScrollPane;
+ private javax.swing.JTextArea correlationValueTextArea;
private javax.swing.JLabel descriptionLabel;
private javax.swing.JLabel errorLabel;
+ private javax.swing.JLabel normalizedLabel;
private javax.swing.JButton searchButton;
// End of variables declaration//GEN-END:variables
}
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties
index e1a434785b..d8043261d8 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties
@@ -1,10 +1,11 @@
-AllCasesSearchDialog.descriptionLabel.text=Search the Central Repository for correlation properties with a specified value. The search is case insensitive.
+AllCasesSearchDialog.descriptionLabel.text=Search the Central Repository for the given values.
AllCasesSearchDialog.errorLabel.text=\
-AllCasesSearchDialog.correlationTypeLabel.text=Correlation Property Type:
+AllCasesSearchDialog.correlationTypeLabel.text=Type:
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription=
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleName=Search
AllCasesSearchDialog.searchButton.text=Search
-AllCasesSearchDialog.correlationValueTextField.text=
-AllCasesSearchDialog.correlationValueLabel.text=Correlation Property Value:
+AllCasesSearchDialog.correlationValueLabel.text=Value:
AllCasesSearchDialog.casesLabel.text=\
+AllCasesSearchDialog.correlationValueTextArea.text=
+AllCasesSearchDialog.normalizedLabel.text=Values will be normalized to ensure consistent case and formatting.
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties-MERGED
index 57f8219cd1..619e29f12a 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle.properties-MERGED
@@ -1,7 +1,7 @@
-AllCasesSearchAction.getName.text=Search All Cases
+AllCasesSearchAction.getName.text=Search Central Repository
# {0} - number of cases
-AllCasesSearchDialog.caseLabel.text=The current Central Repository contains {0} case(s).
+AllCasesSearchDialog.caseLabel.text=The Central Repository contains {0} case(s).
AllCasesSearchDialog.correlationValueTextField.domainExample=Example: "domain.com"
AllCasesSearchDialog.correlationValueTextField.emailExample=Example: "user@host.com"
AllCasesSearchDialog.correlationValueTextField.filesExample=Example: "f0e1d2c3b4a5968778695a4b3c2d1e0f"
@@ -12,19 +12,20 @@ AllCasesSearchDialog.correlationValueTextField.macExample=Example: "0C-14-F2-01-
AllCasesSearchDialog.correlationValueTextField.phoneExample=Example: "(800)123-4567"
AllCasesSearchDialog.correlationValueTextField.ssidExample=Example: "WirelessNetwork-5G"
AllCasesSearchDialog.correlationValueTextField.usbExample=Example: "4&1234567&0"
-AllCasesSearchDialog.descriptionLabel.text=Search the Central Repository for correlation properties with a specified value. The search is case insensitive.
-AllCasesSearchDialog.dialogTitle.text=Search All Cases
+AllCasesSearchDialog.descriptionLabel.text=Search the Central Repository for the given values.
+AllCasesSearchDialog.dialogTitle.text=Search Central Repository
AllCasesSearchDialog.emptyNode.text=No results found.
AllCasesSearchDialog.errorLabel.text=\
-AllCasesSearchDialog.correlationTypeLabel.text=Correlation Property Type:
-AllCasesSearchDialog.resultsDescription.text=All Cases Search
+AllCasesSearchDialog.correlationTypeLabel.text=Type:
+AllCasesSearchDialog.resultsDescription.text=Search Central Repository
AllCasesSearchDialog.resultsTitle.text=All Cases
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription=
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleName=Search
AllCasesSearchDialog.searchButton.text=Search
-AllCasesSearchDialog.correlationValueTextField.text=
-AllCasesSearchDialog.correlationValueLabel.text=Correlation Property Value:
+AllCasesSearchDialog.correlationValueLabel.text=Value:
AllCasesSearchDialog.casesLabel.text=\
+AllCasesSearchDialog.correlationValueTextArea.text=
+AllCasesSearchDialog.normalizedLabel.text=Values will be normalized to ensure consistent case and formatting.
AllCasesSearchDialog.validation.genericMessage=The supplied value is not valid.
AllCasesSearchDialog.validation.invalidDomain=The supplied value is not a valid domain.
AllCasesSearchDialog.validation.invalidEmail=The supplied value is not a valid e-mail address.
@@ -43,4 +44,5 @@ CorrelationAttributeInstanceNode.columnName.device=Device
CorrelationAttributeInstanceNode.columnName.known=Known
CorrelationAttributeInstanceNode.columnName.name=Name
CorrelationAttributeInstanceNode.columnName.path=Path
-CTL_AllCasesSearchAction=Search All Cases
+CorrelationAttributeInstanceNode.columnName.value=Value
+CTL_AllCasesSearchAction=Search Central Repository
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle_ja.properties
index 08a2809615..544d416bc3 100644
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle_ja.properties
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/Bundle_ja.properties
@@ -1,30 +1,29 @@
-
-AllCasesSearchAction.getName.text=\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u3092\u691c\u7d22
-# {0} - \u30b1\u30fc\u30b9\u6570
-AllCasesSearchDialog.caseLabel.text=\u73fe\u5728\u306e\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u306b\u306f {0} \u30b1\u30fc\u30b9\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093\u3002
-AllCasesSearchDialog.correlationValueTextField.domainExample=\u4f8b: "domain.com"
-AllCasesSearchDialog.correlationValueTextField.emailExample=\u4f8b: "user@host.com"
-AllCasesSearchDialog.correlationValueTextField.filesExample=\u4f8b: "f0e1d2c3b4a5968778695a4b3c2d1e0f"
-AllCasesSearchDialog.correlationValueTextField.iccidExample=\u4f8b: "89 91 19 1299 99 329451 0"
-AllCasesSearchDialog.correlationValueTextField.imeiExample=\u4f8b: "351756061523999"
-AllCasesSearchDialog.correlationValueTextField.imsiExample=\u4f8b: "310150123456789"
-AllCasesSearchDialog.correlationValueTextField.macExample=\u4f8b: "0C-14-F2-01-AF-45"
-AllCasesSearchDialog.correlationValueTextField.phoneExample=\u4f8b: "(800)123-4567"
-AllCasesSearchDialog.correlationValueTextField.ssidExample=\u4f8b: "WirelessNetwork-5G"
-AllCasesSearchDialog.correlationValueTextField.usbExample=\u4f8b: "4&1234567&0"
-AllCasesSearchDialog.descriptionLabel.text=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3\u304c\u306a\u3044\u304b\u6307\u5b9a\u5024\u3067\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u3092\u691c\u7d22\u3057\u307e\u3059\u3002\u691c\u7d22\u306f\u5927\u6587\u5b57\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3057\u307e\u305b\u3093\u3002
-AllCasesSearchDialog.dialogTitle.text=\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u3092\u691c\u7d22
+#Thu Sep 30 10:26:58 UTC 2021
+AllCasesSearchAction.getName.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u691c\u7d22
+AllCasesSearchDialog.caseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u306f{0}\u30b1\u30fc\u30b9\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002
+AllCasesSearchDialog.casesLabel.text=\
+AllCasesSearchDialog.correlationTypeLabel.text=\u30bf\u30a4\u30d7\uff1a
+AllCasesSearchDialog.correlationValueLabel.text=\u5024\uff1a
+AllCasesSearchDialog.correlationValueTextField.domainExample=\u4f8b\: "domain.com"
+AllCasesSearchDialog.correlationValueTextField.emailExample=\u4f8b\: "user@host.com"
+AllCasesSearchDialog.correlationValueTextField.filesExample=\u4f8b\: "f0e1d2c3b4a5968778695a4b3c2d1e0f"
+AllCasesSearchDialog.correlationValueTextField.iccidExample=\u4f8b\: "89 91 19 1299 99 329451 0"
+AllCasesSearchDialog.correlationValueTextField.imeiExample=\u4f8b\: "351756061523999"
+AllCasesSearchDialog.correlationValueTextField.imsiExample=\u4f8b\: "310150123456789"
+AllCasesSearchDialog.correlationValueTextField.macExample=\u4f8b\: "0C-14-F2-01-AF-45"
+AllCasesSearchDialog.correlationValueTextField.phoneExample=\u4f8b\: "(800)123-4567"
+AllCasesSearchDialog.correlationValueTextField.ssidExample=\u4f8b\: "WirelessNetwork-5G"
+AllCasesSearchDialog.correlationValueTextField.usbExample=\u4f8b\: "4&1234567&0"
+AllCasesSearchDialog.descriptionLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u6307\u5b9a\u3055\u308c\u305f\u5024\u3092\u691c\u7d22\u3057\u307e\u3059\u3002
+AllCasesSearchDialog.dialogTitle.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u691c\u7d22
AllCasesSearchDialog.emptyNode.text=\u8a72\u5f53\u3059\u308b\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002
AllCasesSearchDialog.errorLabel.text=\
-AllCasesSearchDialog.correlationTypeLabel.text=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3\u30bf\u30a4\u30d7:
-AllCasesSearchDialog.resultsDescription.text=\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u306e\u691c\u7d22
+AllCasesSearchDialog.normalizedLabel.text=\u5927\u6587\u5b57\u3068\u5c0f\u6587\u5b57\u3068\u66f8\u5f0f\u304c\u4e00\u8cab\u3059\u308b\u3088\u3046\u306b\u3001\u5024\u306f\u6b63\u898f\u5316\u3055\u308c\u307e\u3059\u3002
+AllCasesSearchDialog.resultsDescription.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u691c\u7d22
AllCasesSearchDialog.resultsTitle.text=\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription=
AllCasesSearchDialog.searchButton.AccessibleContext.accessibleName=\u691c\u7d22
AllCasesSearchDialog.searchButton.text=\u691c\u7d22
-AllCasesSearchDialog.correlationValueTextField.text=
-AllCasesSearchDialog.correlationValueLabel.text=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3\u5024:
-AllCasesSearchDialog.casesLabel.text=\
AllCasesSearchDialog.validation.genericMessage=\u63d0\u4f9b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
AllCasesSearchDialog.validation.invalidDomain=\u63d0\u4f9b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u306a\u30c9\u30e1\u30a4\u30f3\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
AllCasesSearchDialog.validation.invalidEmail=\u63d0\u4f9b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u306a\u96fb\u5b50\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
@@ -36,6 +35,7 @@ AllCasesSearchDialog.validation.invalidMac=\u63d0\u4f9b\u3055\u308c\u305f\u5024\
AllCasesSearchDialog.validation.invalidPhone=\u63d0\u4f9b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u306a\u96fb\u8a71\u756a\u53f7\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
AllCasesSearchDialog.validation.invalidSsid=\u63d0\u4f9b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u306a\u30ef\u30a4\u30e4\u30ec\u30b9 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
AllCasesSearchNode.getName.text=\u305d\u306e\u4ed6\u306e\u30b1\u30fc\u30b9\u306e\u691c\u7d22
+CTL_AllCasesSearchAction=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u691c\u7d22
CorrelationAttributeInstanceNode.columnName.case=\u30b1\u30fc\u30b9
CorrelationAttributeInstanceNode.columnName.comment=\u30b3\u30e1\u30f3\u30c8
CorrelationAttributeInstanceNode.columnName.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
@@ -43,4 +43,4 @@ CorrelationAttributeInstanceNode.columnName.device=\u30c7\u30d0\u30a4\u30b9
CorrelationAttributeInstanceNode.columnName.known=\u65e2\u77e5
CorrelationAttributeInstanceNode.columnName.name=\u540d\u524d
CorrelationAttributeInstanceNode.columnName.path=\u30d1\u30b9
-CTL_AllCasesSearchAction=\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u3092\u691c\u7d22
+CorrelationAttributeInstanceNode.columnName.value=\u5024
diff --git a/Core/src/org/sleuthkit/autopsy/allcasessearch/CorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/allcasessearch/CorrelationAttributeInstanceNode.java
index 7c77b753d8..e2e57e68d5 100755
--- a/Core/src/org/sleuthkit/autopsy/allcasessearch/CorrelationAttributeInstanceNode.java
+++ b/Core/src/org/sleuthkit/autopsy/allcasessearch/CorrelationAttributeInstanceNode.java
@@ -84,6 +84,7 @@ public final class CorrelationAttributeInstanceNode extends DisplayableItemNode
"CorrelationAttributeInstanceNode.columnName.name=Name",
"CorrelationAttributeInstanceNode.columnName.case=Case",
"CorrelationAttributeInstanceNode.columnName.dataSource=Data Source",
+ "CorrelationAttributeInstanceNode.columnName.value=Value",
"CorrelationAttributeInstanceNode.columnName.known=Known",
"CorrelationAttributeInstanceNode.columnName.path=Path",
"CorrelationAttributeInstanceNode.columnName.comment=Comment",
@@ -109,6 +110,7 @@ public final class CorrelationAttributeInstanceNode extends DisplayableItemNode
final String dataSourceName = dataSource.getName();
final String known = centralRepoFile.getKnownStatus().getName();
final String comment = centralRepoFile.getComment();
+ final String value = centralRepoFile.getCorrelationValue();
final String device = dataSource.getDeviceID();
final String NO_DESCR = "";
@@ -122,6 +124,9 @@ public final class CorrelationAttributeInstanceNode extends DisplayableItemNode
sheetSet.put(new NodeProperty<>(
Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(),
Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), NO_DESCR, dataSourceName));
+ sheetSet.put(new NodeProperty<>(
+ Bundle.CorrelationAttributeInstanceNode_columnName_value(),
+ Bundle.CorrelationAttributeInstanceNode_columnName_value(), NO_DESCR, value));
sheetSet.put(new NodeProperty<>(
Bundle.CorrelationAttributeInstanceNode_columnName_known(),
Bundle.CorrelationAttributeInstanceNode_columnName_known(), NO_DESCR, known));
diff --git a/Core/src/org/sleuthkit/autopsy/apputils/ApplicationLoggers.java b/Core/src/org/sleuthkit/autopsy/apputils/ApplicationLoggers.java
new file mode 100755
index 0000000000..1cd2cf734f
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/apputils/ApplicationLoggers.java
@@ -0,0 +1,103 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2020 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.apputils;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.FileHandler;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+
+/**
+ * A utility that creates and stores application loggers.
+ *
+ * TODO (Jira-7175): This code is the third copy of code that originally
+ * appeared in org.sleuthkit.autopsy.coreutils.Logger. The second copy is in
+ * org.sleuthkit.autopsy.experimental.autoingest.AutoIngestSystemLogger. This
+ * class should allow the replacement of AutoIngestSystemLogger and the
+ * elimination of duplicate code in coreutils.Logger through delegation
+ * (maintaining the public API for coreutils.Logger).
+ */
+final public class ApplicationLoggers {
+
+ private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited.
+ private static final int LOG_FILE_COUNT = 10;
+ private static final String NEWLINE = System.lineSeparator();
+ private static final Map loggers = new HashMap<>();
+
+ /**
+ * Gets the logger for a given application log file. The log file will be
+ * located in the var/log directory of the platform user directory and will
+ * have a name of the form [log name].log.
+ *
+ * @return The logger.
+ */
+ synchronized public static Logger getLogger(String logName) {
+ Logger logger;
+ if (loggers.containsKey(logName)) {
+ logger = loggers.get(logName);
+ } else {
+ logger = Logger.getLogger(logName);
+ Path logFilePath = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath(), "var", "log", String.format("%s.log", logName));
+ try {
+ FileHandler fileHandler = new FileHandler(logFilePath.toString(), LOG_SIZE, LOG_FILE_COUNT);
+ fileHandler.setEncoding(PlatformUtil.getLogFileEncoding());
+ fileHandler.setFormatter(new Formatter() {
+ @Override
+ public String format(LogRecord record) {
+ Throwable thrown = record.getThrown();
+ String stackTrace = ""; //NON-NLS
+ while (thrown != null) {
+ stackTrace += thrown.toString() + NEWLINE;
+ for (StackTraceElement traceElem : record.getThrown().getStackTrace()) {
+ stackTrace += "\t" + traceElem.toString() + NEWLINE; //NON-NLS
+ }
+ thrown = thrown.getCause();
+ }
+ return (new Timestamp(record.getMillis())).toString() + " " //NON-NLS
+ + record.getSourceClassName() + " " //NON-NLS
+ + record.getSourceMethodName() + NEWLINE
+ + record.getLevel() + ": " //NON-NLS
+ + this.formatMessage(record) + NEWLINE
+ + stackTrace;
+ }
+ });
+ logger.addHandler(fileHandler);
+ logger.setUseParentHandlers(false);
+ } catch (SecurityException | IOException ex) {
+ throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS
+ }
+ loggers.put(logName, logger);
+ }
+ return logger;
+ }
+
+ /**
+ * Prevents instantiation of this utility class.
+ */
+ private ApplicationLoggers() {
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/apputils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/apputils/Bundle.properties-MERGED
new file mode 100644
index 0000000000..de7c28c948
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/apputils/Bundle.properties-MERGED
@@ -0,0 +1,4 @@
+CTL_ResetWindowsAction=Reset Windows
+ResetWindowAction.caseCloseFailure.text=Unable to close the current case, the software will restart and the windows locations will reset the next time the software is closed.
+ResetWindowAction.caseSaveMetadata.text=Unable to save current case path, the software will restart and the windows locations will reset but the current case will not be opened upon restart.
+ResetWindowAction.confirm.text=In order to perform the resetting of window locations the software will close and restart. If a case is currently open, it will be closed. If ingest or a search is currently running, it will be terminated. Are you sure you want to restart the software to reset all window locations?
diff --git a/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties
new file mode 100644
index 0000000000..72dd3a972d
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties
@@ -0,0 +1,5 @@
+#Thu Sep 30 10:26:58 UTC 2021
+CTL_ResetWindowsAction=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8
+ResetWindowAction.caseCloseFailure.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u518d\u8d77\u52d5\u3057\u3001\u6b21\u306b\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u9589\u3058\u308b\u3068\u304d\u306b\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u304c\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3059\u3002
+ResetWindowAction.caseSaveMetadata.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u30d1\u30b9\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3002\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u518d\u8d77\u52d5\u3057\u3001\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u306f\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3059\u3002\u518d\u8d77\u52d5\u6642\u306b\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306f\u958b\u304b\u308c\u307e\u305b\u3093\u3002
+ResetWindowAction.confirm.text=\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u306e\u30ea\u30bb\u30c3\u30c8\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u3001\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u9589\u3058\u3066\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002 \u30b1\u30fc\u30b9\u304c\u73fe\u5728\u958b\u3044\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u9589\u3058\u3089\u308c\u307e\u3059\u3002 \u53d6\u308a\u8fbc\u307f\u307e\u305f\u306f\u691c\u7d22\u304c\u73fe\u5728\u5b9f\u884c\u4e2d\u306e\u5834\u5408\u3001\u305d\u308c\u306f\u7d42\u4e86\u3057\u307e\u3059\u3002 \u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u518d\u8d77\u52d5\u3057\u3066\u3001\u3059\u3079\u3066\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f
diff --git a/Core/src/org/sleuthkit/autopsy/apputils/ResetWindowsAction.java b/Core/src/org/sleuthkit/autopsy/apputils/ResetWindowsAction.java
new file mode 100644
index 0000000000..25bacd3761
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/apputils/ResetWindowsAction.java
@@ -0,0 +1,141 @@
+/*
+ * Autopsy
+ *
+ * Copyright 2021 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.apputils;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.logging.Level;
+import javax.swing.SwingUtilities;
+import org.apache.commons.io.FileUtils;
+import org.openide.LifecycleManager;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.casemodule.CaseActionException;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+
+/**
+ * Class to open the Discovery dialog. Allows the user to run searches and see
+ * results in the DiscoveryTopComponent.
+ */
+@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.apputils.ResetWindowsAction")
+@ActionReferences(value = {
+ @ActionReference(path = "Menu/Window", position = 205)})
+@ActionRegistration(displayName = "#CTL_ResetWindowsAction", lazy = false)
+@NbBundle.Messages({"CTL_ResetWindowsAction=Reset Windows"})
+public final class ResetWindowsAction extends CallableSystemAction {
+
+ private static final String DISPLAY_NAME = Bundle.CTL_ResetWindowsAction();
+ private static final long serialVersionUID = 1L;
+ private final static Logger logger = Logger.getLogger(ResetWindowsAction.class.getName());
+ private final static String WINDOWS2LOCAL = "Windows2Local";
+ private final static String CASE_TO_REOPEN_FILE = "caseToOpen.txt";
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @NbBundle.Messages({"ResetWindowAction.confirm.text=In order to perform the resetting of window locations the software will close and restart. "
+ + "If a case is currently open, it will be closed. If ingest or a search is currently running, it will be terminated. "
+ + "Are you sure you want to restart the software to reset all window locations?",
+ "ResetWindowAction.caseCloseFailure.text=Unable to close the current case, "
+ + "the software will restart and the windows locations will reset the next time the software is closed.",
+ "ResetWindowAction.caseSaveMetadata.text=Unable to save current case path, "
+ + "the software will restart and the windows locations will reset but the current case will not be opened upon restart."})
+
+ @Override
+ public void performAction() {
+ SwingUtilities.invokeLater(() -> {
+ boolean response = MessageNotifyUtil.Message.confirm(Bundle.ResetWindowAction_confirm_text());
+ if (response) {
+ //adding the shutdown hook, closing the current case, and marking for restart can be re-ordered if slightly different behavior is desired
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ try {
+ FileUtils.deleteDirectory(new File(PlatformUtil.getUserConfigDirectory() + File.separator + WINDOWS2LOCAL));
+ } catch (IOException ex) {
+ //While we would like the user to be aware of this in the unlikely event that the directory can not be deleted
+ //Because our deletion is being attempted in a shutdown hook I don't know that we can pop up UI elements during the shutdown proces
+ logger.log(Level.SEVERE, "Unable to delete config directory, window locations will not be reset. To manually reset the windows please delete the following directory while the software is closed. " + PlatformUtil.getUserConfigDirectory() + File.separator + "Windows2Local", ex);
+ }
+ }
+ });
+ try {
+ if (Case.isCaseOpen()) {
+ String caseMetadataFilePath = Case.getCurrentCase().getMetadata().getFilePath().toString();
+ File caseToOpenFile = new File(ResetWindowsAction.getCaseToReopenFilePath());
+ Charset encoding = null; //prevents writeStringToFile from having ambiguous arguments
+ FileUtils.writeStringToFile(caseToOpenFile, caseMetadataFilePath, encoding);
+ Case.closeCurrentCase();
+ }
+ // The method markForRestart can not be undone once it is called.
+ LifecycleManager.getDefault().markForRestart();
+ //we need to call exit last
+ LifecycleManager.getDefault().exit();
+ } catch (CaseActionException ex) {
+ logger.log(Level.WARNING, Bundle.ResetWindowAction_caseCloseFailure_text(), ex);
+ MessageNotifyUtil.Message.show(Bundle.ResetWindowAction_caseCloseFailure_text(), MessageNotifyUtil.MessageType.ERROR);
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, Bundle.ResetWindowAction_caseSaveMetadata_text(), ex);
+ MessageNotifyUtil.Message.show(Bundle.ResetWindowAction_caseSaveMetadata_text(), MessageNotifyUtil.MessageType.ERROR);
+ }
+ }
+ });
+ }
+
+ public static String getCaseToReopenFilePath(){
+ return PlatformUtil.getUserConfigDirectory() + File.separator + CASE_TO_REOPEN_FILE;
+ }
+
+ /**
+ * Set this action to be enabled/disabled
+ *
+ * @param value whether to enable this action or not
+ */
+ @Override
+
+ public void setEnabled(boolean value) {
+ super.setEnabled(value);
+ }
+
+ @Override
+ public String getName() {
+ return DISPLAY_NAME;
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public boolean asynchronous() {
+ return false; // run on edt
+ }
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
index 53320d9313..310051b7f5 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
@@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.imagewriter.ImageWriterService;
import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
import org.sleuthkit.datamodel.AddDataSourceCallbacks;
import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitJNI;
import org.sleuthkit.datamodel.TskCoreException;
@@ -316,7 +317,7 @@ class AddImageTask implements Runnable {
boolean ignoreFatOrphanFiles;
String md5;
String sha1;
- String sha256;
+ String sha256;
ImageWriterSettings imageWriterSettings;
ImageDetails(String deviceId, Image image, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, ImageWriterSettings imageWriterSettings) {
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java
index 2b880093e9..58b1bb5a56 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java
@@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.datamodel.Host;
/**
* The final panel of the add image wizard. It displays a progress bar and
@@ -115,7 +116,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
}
});
}
-
+
@Override
public void setProgressMax(final int max) {
// update the progress bar asynchronously
@@ -302,7 +303,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
private void startIngest() {
if (!newContents.isEmpty() && readyToIngest && !ingested) {
ingested = true;
- if (dsProcessor != null && ! dsProcessor.supportsIngestStream()) {
+ if (dsProcessor != null && !dsProcessor.supportsIngestStream()) {
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings);
}
setStateFinished();
@@ -323,51 +324,56 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
/**
* Starts the Data source processing by kicking off the selected
* DataSourceProcessor
+ *
+ * @param dsp The data source processor providing configuration for
+ * how to process the specific data source type.
+ * @param selectedHost The host to which this data source belongs or null
+ * for a default host.
*/
- void startDataSourceProcessing(DataSourceProcessor dsp) {
+ void startDataSourceProcessing(DataSourceProcessor dsp, Host selectedHost) {
if (dsProcessor == null) { //this can only be run once
final UUID dataSourceId = UUID.randomUUID();
newContents.clear();
cleanupTask = null;
- readyToIngest = false;
dsProcessor = dsp;
-
- // Add a cleanup task to interrupt the background process if the
- // wizard exits while the background process is running.
- cleanupTask = addImageAction.new CleanupTask() {
- @Override
- void cleanup() throws Exception {
- WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- cancelDataSourceProcessing(dataSourceId);
- cancelled = true;
- WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }
- };
-
- cleanupTask.enable();
-
new Thread(() -> {
+ // Add a cleanup task to interrupt the background process if the
+ // wizard exits while the background process is running.
+ cleanupTask = addImageAction.new CleanupTask() {
+ @Override
+ void cleanup() throws Exception {
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ cancelDataSourceProcessing(dataSourceId);
+ cancelled = true;
+ WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ };
+
+ cleanupTask.enable();
+
try {
Case.getCurrentCaseThrows().notifyAddingDataSource(dataSourceId);
} catch (NoCurrentCaseException ex) {
- Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
+ Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
+ }
+
+ DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
+ @Override
+ public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List errList, List contents) {
+ dataSourceProcessorDone(dataSourceId, result, errList, contents);
+ }
+ };
+
+ // Kick off the DSProcessor
+ if (dsProcessor.supportsIngestStream()) {
+ // Set readyToIngest to false to prevent the wizard from starting ingest a second time.
+ readyToIngest = false;
+ dsProcessor.runWithIngestStream(selectedHost, ingestJobSettings, getDSPProgressMonitorImpl(), cbObj);
+ } else {
+ dsProcessor.run(selectedHost, getDSPProgressMonitorImpl(), cbObj);
}
}).start();
- DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
- @Override
- public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List errList, List contents) {
- dataSourceProcessorDone(dataSourceId, result, errList, contents);
- }
- };
-
setStateStarted();
-
- // Kick off the DSProcessor
- if (dsProcessor.supportsIngestStream()) {
- dsProcessor.runWithIngestStream(ingestJobSettings, getDSPProgressMonitorImpl(), cbObj);
- } else {
- dsProcessor.run(getDSPProgressMonitorImpl(), cbObj);
- }
}
}
@@ -419,9 +425,14 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
// TBD: there probably should be an error level for each error
addErrors(err, critErr);
}
-
- //notify the UI of the new content added to the case
+ final Level level = critErr ? Level.SEVERE : Level.WARNING;
new Thread(() -> {
+ //log error messages as Severe if there was a critical error otherwise as Warning.
+ //logging performed off of UI thread
+ for (String err : errList) {
+ Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(level, "DatasourceID: {0} Error Message: {1}", new Object[]{dataSourceId.toString(), err});
+ }
+ //notify the UI of the new content added to the case
try {
if (!contents.isEmpty()) {
Case.getCurrentCaseThrows().notifyDataSourceAdded(contents.get(0), dataSourceId);
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java
index d44b3ed522..320a2200f7 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2018 Basis Technology Corp.
+ * Copyright 2011-2020 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,6 +33,7 @@ import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.python.JythonModuleLoader;
/**
* visual component for the first panel of add image wizard. Allows the user to
@@ -76,6 +77,14 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel {
logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
}
}
+
+ for (DataSourceProcessor dsProcessor : JythonModuleLoader.getDataSourceProcessorModules()) {
+ if (!datasourceProcessorsMap.containsKey(dsProcessor.getDataSourceType())) {
+ datasourceProcessorsMap.put(dsProcessor.getDataSourceType(), dsProcessor);
+ } else {
+ logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
+ }
+ }
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java
index cfcbdd015c..7097b592c3 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java
@@ -28,6 +28,7 @@ import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.ingest.profile.IngestProfilePaths;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
@@ -43,7 +44,7 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
- @Messages("AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules")
+ @Messages("AddImageWizardIngestConfigPanel.name.text=Configure Ingest")
private final IngestJobSettingsPanel ingestJobSettingsPanel;
/**
* The visual component that displays this panel. If you need to access the
@@ -189,7 +190,8 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
}
//Because this panel kicks off ingest during the wizard we need to
//swap out the ingestJobSettings for the ones of the chosen profile before
- IngestJobSettings ingestJobSettings = new IngestJobSettings(lastProfileUsed);
+ //use prefix to specify correct execution context for profiles.
+ IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestProfilePaths.getInstance().getIngestProfilePrefix() + lastProfileUsed);
progressPanel.setIngestJobSettings(ingestJobSettings); //prepare ingest for being started
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java
index 045bf775b2..9ed66765d3 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java
@@ -29,6 +29,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.ingest.IngestProfiles;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestProfileSelectionWizardPanel;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
+import org.sleuthkit.datamodel.Host;
/**
* The iterator class for the "Add Image" wizard panel. This class is used to
@@ -41,8 +42,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator getPanels() {
if (panels == null) {
panels = new ArrayList<>();
+ hostPanel = new AddImageWizardSelectHostPanel();
+ panels.add(hostPanel);
+ hostPanelIndex = panels.indexOf(hostPanel);
AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel();
panels.add(dspSelection);
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action);
-
AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel();
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel);
panels.add(dsPanel);
@@ -164,7 +169,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator 0); //Users should be able to back up to select a different DSP
}
/**
@@ -180,8 +185,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,6 +42,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datasourceprocessors.RawDSProcessor;
import org.sleuthkit.autopsy.logicalimager.dsp.LogicalImagerDSProcessor;
+import org.sleuthkit.autopsy.python.JythonModuleLoader;
/**
* Panel which displays the available DataSourceProcessors and allows selection
@@ -196,6 +197,15 @@ final class AddImageWizardSelectDspVisual extends JPanel {
logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
}
}
+
+ for (DataSourceProcessor dsProcessor : JythonModuleLoader.getDataSourceProcessorModules()) {
+ if (!datasourceProcessorsMap.containsKey(dsProcessor.getDataSourceType())) {
+ datasourceProcessorsMap.put(dsProcessor.getDataSourceType(), dsProcessor);
+ } else {
+ logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
+ }
+ }
+
dspList.add(ImageDSProcessor.getType());
dspList.add(LocalDiskDSProcessor.getType());
dspList.add(LocalFilesDSProcessor.getType());
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java
new file mode 100644
index 0000000000..738ea66494
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java
@@ -0,0 +1,96 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2021 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.casemodule;
+
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.ChangeSupport;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle.Messages;
+import org.sleuthkit.datamodel.Host;
+import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
+
+/**
+ * Create a wizard panel which contains a panel allowing the selection of a host
+ * for a data source.
+ */
+@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
+@Messages("AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To")
+final class AddImageWizardSelectHostPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener {
+
+ private final AddImageWizardSelectHostVisual component = new AddImageWizardSelectHostVisual();
+ private final ChangeSupport changeSupport = new ChangeSupport(this);
+
+ AddImageWizardSelectHostPanel() {
+ component.addListener(this);
+ }
+
+ @Override
+ public Component getComponent() {
+ return component;
+ }
+
+ @Override
+ public HelpCtx getHelp() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public void readSettings(WizardDescriptor data) {
+ }
+
+ /**
+ * Returns or generates the selected host. If user specifies 'generate
+ * new...', then null will be returned.
+ *
+ * @return The selected host or null if to be auto generated.
+ */
+ Host getSelectedHost() {
+ return component.getSelectedHost();
+ }
+
+ @Override
+ public void storeSettings(WizardDescriptor data) {
+ }
+
+ @Override
+ public boolean isValid() {
+ return component.hasValidData();
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener cl) {
+ changeSupport.addChangeListener(cl);
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener cl) {
+ changeSupport.removeChangeListener(cl);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ changeSupport.fireChange();
+ }
+
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form
new file mode 100644
index 0000000000..bdb977932a
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form
@@ -0,0 +1,163 @@
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java
new file mode 100644
index 0000000000..07eaf84104
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java
@@ -0,0 +1,374 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2021 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.casemodule;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.stream.Collectors;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.apache.commons.lang.StringUtils;
+import org.openide.util.NbBundle.Messages;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.datamodel.hosts.HostNameValidator;
+import org.sleuthkit.datamodel.Host;
+import org.sleuthkit.datamodel.TskCoreException;
+
+/**
+ * Panel to be displayed as a part of the add datasource wizard. Provides the
+ * ability to select current host.
+ */
+@Messages({
+ "AddImageWizardSelectHostVisual_title=Select Host"
+})
+class AddImageWizardSelectHostVisual extends javax.swing.JPanel {
+
+ /**
+ * A combo box item for a host (or null for default).
+ */
+ private static class HostListItem {
+
+ private final Host host;
+
+ /**
+ * Main constructor.
+ *
+ * @param host The host.
+ */
+ HostListItem(Host host) {
+ this.host = host;
+ }
+
+ /**
+ * @return The host.
+ */
+ Host getHost() {
+ return host;
+ }
+
+ @Override
+ public String toString() {
+ if (host == null || host.getName() == null) {
+ return "";
+ } else {
+ return host.getName();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getHostId());
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final HostListItem other = (HostListItem) obj;
+ if (!Objects.equals(
+ this.host == null ? 0 : this.host.getHostId(),
+ other.host == null ? 0 : other.host.getHostId())) {
+
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ private static final Logger logger = Logger.getLogger(AddImageWizardSelectHostVisual.class.getName());
+
+ private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
+ private Set sanitizedHostSet = null;
+
+ /**
+ * Creates new form SelectHostPanel
+ */
+ AddImageWizardSelectHostVisual() {
+ initComponents();
+
+ specifyNewHostTextField.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ refresh();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ refresh();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ refresh();
+ }
+ });
+
+ existingHostList.addListSelectionListener((evt) -> refresh());
+
+ loadHostData();
+ refresh();
+ }
+
+ /**
+ * Add listener for validation change events.
+ *
+ * @param pcl The property change listener.
+ */
+ void addListener(PropertyChangeListener pcl) {
+ changeSupport.addPropertyChangeListener(pcl);
+ }
+
+ /**
+ * Remove listener from validation change events.
+ *
+ * @param pcl The property change listener.
+ */
+ void removeListener(PropertyChangeListener pcl) {
+ changeSupport.removePropertyChangeListener(pcl);
+ }
+
+ /**
+ * @return The currently selected host or null if no selection. This will
+ * generate a new host if 'Specify New Host Name'
+ */
+ Host getSelectedHost() {
+ if (specifyNewHostRadio.isSelected() && StringUtils.isNotEmpty(specifyNewHostTextField.getText())) {
+ String newHostName = specifyNewHostTextField.getText();
+ try {
+ return Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().newHost(newHostName);
+ } catch (NoCurrentCaseException | TskCoreException ex) {
+ logger.log(Level.WARNING, String.format("Unable to create host '%s'.", newHostName), ex);
+ return null;
+ }
+ } else if (useExistingHostRadio.isSelected()
+ && existingHostList.getSelectedValue() != null
+ && existingHostList.getSelectedValue().getHost() != null) {
+
+ return existingHostList.getSelectedValue().getHost();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Loads hosts from database and displays in combo box.
+ */
+ private void loadHostData() {
+ try {
+ Collection hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getAllHosts();
+ sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts);
+
+ Vector hostListItems = hosts.stream()
+ .filter(h -> h != null)
+ .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b)))
+ .map((h) -> new HostListItem(h))
+ .collect(Collectors.toCollection(Vector::new));
+
+ existingHostList.setListData(hostListItems);
+ } catch (NoCurrentCaseException | TskCoreException ex) {
+ logger.log(Level.WARNING, "Unable to display host items with no current case.", ex);
+ }
+ }
+
+ /**
+ * Returns the name of the host or an empty string if the host or host name
+ * is null.
+ *
+ * @param host The host.
+ * @return The host name or empty string.
+ */
+ private String getNameOrEmpty(Host host) {
+ return host == null || host.getName() == null ? "" : host.getName();
+ }
+
+ private void refresh() {
+ specifyNewHostTextField.setEnabled(specifyNewHostRadio.isSelected());
+ existingHostList.setEnabled(useExistingHostRadio.isSelected());
+
+ String prevValidationMessage = validationMessage.getText();
+ String newValidationMessage = getValidationMessage();
+ validationMessage.setText(newValidationMessage);
+ // if validation message changed (empty to non-empty or vice-versa) fire validation update
+ if (StringUtils.isBlank(prevValidationMessage) != StringUtils.isBlank(newValidationMessage)) {
+ changeSupport.firePropertyChange("validation", prevValidationMessage, newValidationMessage);
+ }
+ }
+
+ @Messages({
+ "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",})
+ private String getValidationMessage() {
+ if (specifyNewHostRadio.isSelected()) {
+ // if problematic new name for host
+ return HostNameValidator.getValidationMessage(specifyNewHostTextField.getText(), null, sanitizedHostSet);
+
+ // or use existing host and no host is selected
+ } else if (useExistingHostRadio.isSelected()
+ && (existingHostList.getSelectedValue() == null
+ || existingHostList.getSelectedValue().getHost() == null)) {
+ return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected();
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return Bundle.AddImageWizardSelectHostVisual_title();
+ }
+
+ boolean hasValidData() {
+ return StringUtils.isBlank(validationMessage.getText());
+ }
+
+ /**
+ * 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")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ javax.swing.ButtonGroup radioButtonGroup = new javax.swing.ButtonGroup();
+ generateNewRadio = new javax.swing.JRadioButton();
+ specifyNewHostRadio = new javax.swing.JRadioButton();
+ specifyNewHostTextField = new javax.swing.JTextField();
+ useExistingHostRadio = new javax.swing.JRadioButton();
+ javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
+ existingHostList = new javax.swing.JList<>();
+ hostDescription = new javax.swing.JLabel();
+ validationMessage = new javax.swing.JLabel();
+
+ radioButtonGroup.add(generateNewRadio);
+ generateNewRadio.setSelected(true);
+ org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.generateNewRadio.text")); // NOI18N
+ generateNewRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ generateNewRadioActionPerformed(evt);
+ }
+ });
+
+ radioButtonGroup.add(specifyNewHostRadio);
+ org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostRadio.text")); // NOI18N
+ specifyNewHostRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ specifyNewHostRadioActionPerformed(evt);
+ }
+ });
+
+ specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostTextField.text")); // NOI18N
+
+ radioButtonGroup.add(useExistingHostRadio);
+ org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.useExistingHostRadio.text")); // NOI18N
+ useExistingHostRadio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ useExistingHostRadioActionPerformed(evt);
+ }
+ });
+
+ existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+ jScrollPane1.setViewportView(existingHostList);
+
+ org.openide.awt.Mnemonics.setLocalizedText(hostDescription, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.hostDescription.text")); // NOI18N
+
+ validationMessage.setForeground(java.awt.Color.RED);
+ org.openide.awt.Mnemonics.setLocalizedText(validationMessage, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.validationMessage.text")); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(validationMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(generateNewRadio)
+ .addComponent(useExistingHostRadio)
+ .addComponent(hostDescription)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(21, 21, 21)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(specifyNewHostRadio)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGap(0, 13, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(hostDescription)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(generateNewRadio)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(specifyNewHostRadio)
+ .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(useExistingHostRadio)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(10, 10, 10)
+ .addComponent(validationMessage)
+ .addContainerGap(18, Short.MAX_VALUE))
+ );
+ }// //GEN-END:initComponents
+
+ private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateNewRadioActionPerformed
+ refresh();
+ }//GEN-LAST:event_generateNewRadioActionPerformed
+
+ private void specifyNewHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyNewHostRadioActionPerformed
+ refresh();
+ }//GEN-LAST:event_specifyNewHostRadioActionPerformed
+
+ private void useExistingHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useExistingHostRadioActionPerformed
+ refresh();
+ }//GEN-LAST:event_useExistingHostRadioActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JList existingHostList;
+ private javax.swing.JRadioButton generateNewRadio;
+ private javax.swing.JLabel hostDescription;
+ private javax.swing.JRadioButton specifyNewHostRadio;
+ private javax.swing.JTextField specifyNewHostTextField;
+ private javax.swing.JRadioButton useExistingHostRadio;
+ private javax.swing.JLabel validationMessage;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddLocalFilesTask.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddLocalFilesTask.java
index 185f696a97..6e4a71440f 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddLocalFilesTask.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddLocalFilesTask.java
@@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.LocalFilesDataSource;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
@@ -42,6 +43,7 @@ class AddLocalFilesTask implements Runnable {
private static final Logger LOGGER = Logger.getLogger(AddLocalFilesTask.class.getName());
private final String deviceId;
private final String rootVirtualDirectoryName;
+ private final Host host;
private final List localFilePaths;
private final DataSourceProcessorProgressMonitor progress;
private final DataSourceProcessorCallback callback;
@@ -64,14 +66,16 @@ class AddLocalFilesTask implements Runnable {
* form: LogicalFileSet[N]
* @param localFilePaths A list of localFilePaths of local/logical
* files and/or directories.
+ * @param host The host for this data source (may be null).
* @param progressMonitor Progress monitor to report progress
* during processing.
* @param callback Callback to call when processing is done.
*/
- AddLocalFilesTask(String deviceId, String rootVirtualDirectoryName, List localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
+ AddLocalFilesTask(String deviceId, String rootVirtualDirectoryName, List localFilePaths, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
this.deviceId = deviceId;
this.rootVirtualDirectoryName = rootVirtualDirectoryName;
this.localFilePaths = localFilePaths;
+ this.host = host;
this.callback = callback;
this.progress = progressMonitor;
}
@@ -88,7 +92,7 @@ class AddLocalFilesTask implements Runnable {
try {
progress.setIndeterminate(true);
FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
- LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, "", localFilePaths, new ProgressUpdater());
+ LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, "", host, localFilePaths, new ProgressUpdater());
newDataSources.add(newDataSource);
} catch (TskDataException | TskCoreException | NoCurrentCaseException ex) {
errors.add(ex.getMessage());
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
index 987323a52b..1a6186b2c2 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
@@ -4,7 +4,6 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case
CTL_CaseDetailsAction=Case Details
CTL_CaseDeleteAction=Delete Case
-Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:
@@ -59,7 +58,7 @@ AddImageWizardChooseDataSourcePanel.moveFocusNext=Next >
AddImageWizardChooseDataSourceVisual.getName.text=Select Data Source
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*Data Source added.
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in adding Data Source.
-AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules
+AddImageWizardIngestConfigVisual.getName.text=Configure Ingest
AddImageWizardIterator.stepXofN=Step {0} of {1}
AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1}
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
@@ -146,13 +145,14 @@ AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system
NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive.
+NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
MissingImageDialog.lbWarning.text=
MissingImageDialog.lbWarning.toolTipText=
NewCaseVisualPanel1.caseParentDirWarningLabel.text=
-NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user
-NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user
+NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User
+NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
SingleUserCaseConverter.AlreadyMultiUser=Case is already multi-user!
@@ -257,3 +257,9 @@ SolrNotConfiguredDialog.okButton.text=OK
SolrNotConfiguredDialog.title=Solr 8 Server Not Configured
SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User.
SolrNotConfiguredDialog.messageLabel.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n
+AddImageWizardSelectHostVisual.hostDescription.text=Hosts are used to organize data sources and other data.
+AddImageWizardSelectHostVisual.useExistingHostRadio.text=Use existing host
+AddImageWizardSelectHostVisual.specifyNewHostTextField.text=
+AddImageWizardSelectHostVisual.specifyNewHostRadio.text=Specify new host name
+AddImageWizardSelectHostVisual.generateNewRadio.text=Generate new host name based on data source name
+AddImageWizardSelectHostVisual.validationMessage.text=\
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
index e59c37fea7..528d3a5088 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
@@ -1,5 +1,8 @@
-AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules
+AddImageWizardIngestConfigPanel.name.text=Configure Ingest
AddImageWizardSelectDspVisual.multiUserWarning.text=This type of Data Source Processor is not available in multi-user mode
+AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To
+AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.
+AddImageWizardSelectHostVisual_title=Select Host
# {0} - exception message
Case.closeException.couldNotCloseCase=Error closing case: {0}
Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources
@@ -52,8 +55,8 @@ Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.
Case.exceptionMessage.metadataUpdateError=Failed to update case metadata
# {0} - exception message
Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.
-Case.lockingException.couldNotAcquireExclusiveLock=Failed to get a exclusive lock on the case.
-Case.lockingException.couldNotAcquireSharedLock=Failed to get an shared lock on the case.
+Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case.
+Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.
Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User.
# {0} - image
Case.openFileSystems.openingImage=Opening all filesystems for image: {0}...
@@ -125,6 +128,7 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case
CTL_CaseDetailsAction=Case Details
CTL_CaseDeleteAction=Delete Case
+CTL_CaseDeleteAction=Delete Case
CTL_CaseOpenAction=Open Case
CTL_UnpackagePortableCaseAction=Unpack and Open Portable Case
DeleteDataSourceAction.confirmationDialog.message=Are you sure you want to remove the selected data source from the case?\nNote that the case will be closed and re-opened during the removal.
@@ -183,8 +187,6 @@ LogicalEvidenceFilePanel.pathValidation.getOpenCase.Error=Warning: Exception whi
LogicalEvidenceFilePanel.validatePanel.nonL01Error.text=Only files with the .l01 file extension are supported here.
LogicalFilesDspPanel.subTypeComboBox.l01FileOption.text=Logical evidence file (L01)
LogicalFilesDspPanel.subTypeComboBox.localFilesOption.text=Local files and folders
-Menu/Case/OpenRecentCase=Open Recent Case
-CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:
NewCaseVisualPanel1.caseDirLabel.text=Base Directory:
@@ -242,7 +244,7 @@ AddImageWizardChooseDataSourcePanel.moveFocusNext=Next >
AddImageWizardChooseDataSourceVisual.getName.text=Select Data Source
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*Data Source added.
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in adding Data Source.
-AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules
+AddImageWizardIngestConfigVisual.getName.text=Configure Ingest
AddImageWizardIterator.stepXofN=Step {0} of {1}
AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1}
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
@@ -341,8 +343,14 @@ RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of rang
RecentCases.getName.text=Clear Recent Cases
# {0} - case name
RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.
-SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add
+SelectDataSourceProcessorPanel.name.text=Select Data Source Type
StartupWindow.title.text=Welcome
+# {0} - autFilePath
+StartupWindowProvider.openCase.cantOpen=Unable to open previously open case with metadata file: {0}
+# {0} - reOpenFilePath
+StartupWindowProvider.openCase.deleteOpenFailure=Unable to open or delete file containing path {0} to previously open case. The previous case will not be opened.
+# {0} - autFilePath
+StartupWindowProvider.openCase.noFile=Unable to open previously open case because metadata file not found at: {0}
UnpackagePortableCaseDialog.title.text=Unpackage Portable Case
UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001)
UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001
@@ -364,13 +372,14 @@ AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system
NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive.
+NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
MissingImageDialog.lbWarning.text=
MissingImageDialog.lbWarning.toolTipText=
NewCaseVisualPanel1.caseParentDirWarningLabel.text=
-NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user
-NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user
+NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User
+NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
SingleUserCaseConverter.AlreadyMultiUser=Case is already multi-user!
@@ -475,3 +484,9 @@ SolrNotConfiguredDialog.okButton.text=OK
SolrNotConfiguredDialog.title=Solr 8 Server Not Configured
SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User.
SolrNotConfiguredDialog.messageLabel.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n
+AddImageWizardSelectHostVisual.hostDescription.text=Hosts are used to organize data sources and other data.
+AddImageWizardSelectHostVisual.useExistingHostRadio.text=Use existing host
+AddImageWizardSelectHostVisual.specifyNewHostTextField.text=
+AddImageWizardSelectHostVisual.specifyNewHostRadio.text=Specify new host name
+AddImageWizardSelectHostVisual.generateNewRadio.text=Generate new host name based on data source name
+AddImageWizardSelectHostVisual.validationMessage.text=\
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
index 5f29c9ed07..fe2abb9561 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
@@ -1,4 +1,4 @@
-#Tue Aug 18 18:09:20 UTC 2020
+#Thu Sep 30 10:26:59 UTC 2021
AddImageAction.ingestConfig.ongoingIngest.msg=\u5225\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u65b0\u898f\u30bd\u30fc\u30b9\u3092\u4eca\u8ffd\u52a0\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u51e6\u7406\u304c\u9045\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b?
AddImageAction.ingestConfig.ongoingIngest.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059
AddImageAction.wizard.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
@@ -25,10 +25,17 @@ AddImageWizardChooseDataSourceVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u53d6\u308a\u6d88\u3057
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002
-AddImageWizardIngestConfigPanel.name.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210
-AddImageWizardIngestConfigVisual.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210
+AddImageWizardIngestConfigPanel.name.text=\u53d6\u8fbc\u307f\u3092\u8a2d\u5b9a
+AddImageWizardIngestConfigVisual.getName.text=\u53d6\u8fbc\u307f\u3092\u8a2d\u5b9a
AddImageWizardIterator.stepXofN=\u624b\u9806 {0} / {1}
AddImageWizardSelectDspVisual.multiUserWarning.text=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30e2\u30fc\u30c9\u3067\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
+AddImageWizardSelectHostPanel_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3059\u308b\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002
+AddImageWizardSelectHostVisual.generateNewRadio.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\u306b\u57fa\u3065\u3044\u3066\u65b0\u3057\u3044\u30db\u30b9\u30c8\u540d\u3092\u751f\u6210
+AddImageWizardSelectHostVisual.hostDescription.text=\u30db\u30b9\u30c8\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3084\u305d\u306e\u4ed6\u306e\u30c7\u30fc\u30bf\u3092\u6574\u7406\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002
+AddImageWizardSelectHostVisual.specifyNewHostRadio.text=\u65b0\u3057\u3044\u30db\u30b9\u30c8\u540d\u3092\u6307\u5b9a\u3057\u3066\u4e0b\u3055\u3044
+AddImageWizardSelectHostVisual.useExistingHostRadio.text=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u3092\u4f7f\u7528\u3059\u308b
+AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+AddImageWizardSelectHostVisual_title=\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044
AddLocalFilesTask.localFileAdd.progress.text=\u6b21\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\: {0}/{1}
CTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
@@ -60,6 +67,7 @@ Case.deleteCaseFailureMessageBox.title=\u30b1\u30fc\u30b9\u3092\u524a\u9664\u306
Case.deleteReports.deleteFromDiskException.log.msg=\u30c7\u30a3\u30b9\u30af\u304b\u3089\u30ec\u30dd\u30fc\u30c8\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
Case.deleteReports.deleteFromDiskException.msg=\u30c7\u30a3\u30b9\u30af\u304b\u3089\u30ec\u30dd\u30fc\u30c8 {0} \u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\n{1} \u304b\u3089\u624b\u52d5\u3067\u524a\u9664\u3067\u304d\u307e\u3059
Case.exception.errGetRootObj=\u30eb\u30fc\u30c8\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
+Case.exceptionMessage.cancelled=\u30ad\u30e3\u30f3\u30bb\u30eb\u3002
Case.exceptionMessage.cancelledByUser=\u30e6\u30fc\u30b6\u30fc\u306b\u3088\u3063\u3066\u53d6\u308a\u6d88\u3055\u308c\u307e\u3057\u305f\u3002
Case.exceptionMessage.cannotDeleteCurrentCase=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\u6700\u521d\u306b\u9589\u3058\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
Case.exceptionMessage.cannotGetLockToDeleteCase=\u5225\u306e\u30e6\u30fc\u30b6\u30fc\u307e\u305f\u306f\u30db\u30b9\u30c8\u304c\u958b\u3044\u3066\u3044\u308b\u305f\u3081\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
@@ -74,9 +82,12 @@ Case.exceptionMessage.couldNotOpenRemoteEventChannel=\u30ea\u30e2\u30fc\u30c8\u3
Case.exceptionMessage.couldNotSaveCaseMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\u3092\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
Case.exceptionMessage.couldNotUpdateCaseNodeData=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
+Case.exceptionMessage.dataSourceNotFound=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
Case.exceptionMessage.deletionInterrupted=\u30b1\u30fc\u30b9 {0} \u306e\u524a\u9664\u304c\u53d6\u308a\u6d88\u3055\u308c\u307e\u3057\u305f\u3002
Case.exceptionMessage.emptyCaseDir=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u30d1\u30b9\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
Case.exceptionMessage.emptyCaseName=\u30b1\u30fc\u30b9\u540d\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
+Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
+Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
Case.exceptionMessage.errorsDeletingCase=\u30b1\u30fc\u30b9\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u8a73\u7d30\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
Case.exceptionMessage.execExceptionWrapperMessage={0}
Case.exceptionMessage.failedToConnectToCoordSvc=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}.
@@ -86,16 +97,19 @@ Case.exceptionMessage.failedToReadMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\
Case.exceptionMessage.metadataUpdateError=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
Case.exceptionMessage.unsupportedSchemaVersionMessage=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059\:\n{0}\u3002
Case.getCurCase.exception.noneOpen=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u304c\u958b\u304b\u308c\u3066\u3044\u307e\u305b\u3093\!
+Case.lockingException.couldNotAcquireExclusiveLock=\u30b1\u30fc\u30b9\u306e\u6392\u4ed6\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
+Case.lockingException.couldNotAcquireSharedLock=\u30b1\u30fc\u30b9\u306e\u5171\u6709\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
Case.metaDataFileCorrupt.exception.msg=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb(.aut)\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002
Case.open.exception.multiUserCaseNotEnabled=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u3067\u306a\u3044\u5834\u5408\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002[\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
Case.open.msgDlg.updated.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\:\n {0}
Case.open.msgDlg.updated.title=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u306e\u66f4\u65b0
-Case.openFileSystems.openingImage=\u753b\u50cf\u306e\u3059\u3079\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u3092\u958b\u304f\uff1a{0}\u2026
-Case.openFileSystems.retrievingImages=\u30b1\u30fc\u30b9\u306e\u753b\u50cf\u3092\u53d6\u5f97\u4e2d\uff1a{0}\u2026
+Case.openFileSystems.openingImage=\u30a4\u30e1\u30fc\u30b8\u7528\u306b\u3059\u3079\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u3092\u958b\u304f\uff1a{0} ...
+Case.openFileSystems.retrievingImages=\u30b1\u30fc\u30b9\u306e\u753b\u50cf\u3092\u53d6\u5f97\u3057\u3066\u3044\u307e\u3059\uff1a{0} ...
Case.progressIndicatorCancelButton.label=\u53d6\u308a\u6d88\u3057
Case.progressIndicatorTitle.closingCase=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u3044\u307e\u3059
Case.progressIndicatorTitle.creatingCase=\u30b1\u30fc\u30b9\u3092\u4f5c\u6210\u4e2d\u3067\u3059
Case.progressIndicatorTitle.deletingCase=\u30b1\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u3067\u3059
+Case.progressIndicatorTitle.deletingDataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u524a\u9664\u4e2d
Case.progressIndicatorTitle.openingCase=\u30b1\u30fc\u30b9\u3092\u958b\u3044\u3066\u3044\u307e\u3059
Case.progressMessage.cancelling=\u53d6\u308a\u6d88\u3057\u4e2d\u3067\u3059...
Case.progressMessage.clearingTempDirectory=\u30b1\u30fc\u30b9\u306e\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u6d88\u53bb\u4e2d\u3067\u3059...
@@ -109,6 +123,7 @@ Case.progressMessage.creatingCaseNodeData=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u
Case.progressMessage.deletingCaseDatabase=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u3067\u3059...
Case.progressMessage.deletingCaseDirCoordSvcNode=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u524a\u9664\u4e2d\u3067\u3059...
Case.progressMessage.deletingCaseDirectory=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u524a\u9664\u4e2d\u3067\u3059...
+Case.progressMessage.deletingDataSource=\u30b1\u30fc\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d...
Case.progressMessage.deletingResourcesCoordSvcNode=\u30b1\u30fc\u30b9\u30ea\u30bd\u30fc\u30b9\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u524a\u9664\u4e2d\u3067\u3059...
Case.progressMessage.deletingTextIndex=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u524a\u9664\u4e2d\u3067\u3059...
Case.progressMessage.fetchingCoordSvcNodeData=\u30b1\u30fc\u30b9\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u3067\u3059...
@@ -179,6 +194,11 @@ CueBannerPanel.openCaseLabel.text=\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.openRecentCaseButton.text=
CueBannerPanel.openRecentCaseLabel.text=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.title.text=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
+DeleteDataSourceAction.confirmationDialog.message=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u30b1\u30fc\u30b9\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f\n\u6ce8\u610f\uff1a\u524a\u9664\u4e2d\u306b\u30b1\u30fc\u30b9\u304c\u9589\u3058\u3089\u308c\u3001\u518d\u3073\u958b\u304b\u308c\u307e\u3059\u3002\u300d
+DeleteDataSourceAction.exceptionMessage.couldNotReopenCase=\u30b1\u30fc\u30b9\u3092\u518d\u958b\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a\n{0}\n\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+DeleteDataSourceAction.exceptionMessage.dataSourceDeletionError=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a\n{0}\n\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+DeleteDataSourceAction.ingestRunningWarningDialog.message=\u53d6\u8fbc\u307f\u306e\u5b9f\u884c\u4e2d\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u30b1\u30fc\u30b9\u304b\u3089\u524a\u9664\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002
+DeleteDataSourceAction.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u3059\u308b
EditOptionalCasePropertiesPanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
EditOptionalCasePropertiesPanel.saveButton.text=\u4fdd\u5b58
GeneralFilter.encaseImageDesc.text=\u30a4\u30e1\u30fc\u30b8(*.e01)\u3092\u5305\u542b
@@ -297,7 +317,6 @@ LogicalEvidenceFilePanel.selectButton.toolTipText=\u30ed\u30fc\u30ab\u30eb\u30d5
LogicalEvidenceFilePanel.validatePanel.nonL01Error.text=\u3053\u3053\u3067\u306f .l01\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u306e\u307f\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002
LogicalFilesDspPanel.subTypeComboBox.l01FileOption.text=\u8ad6\u7406\u8a3c\u62e0\u30d5\u30a1\u30a4\u30eb(L01)
LogicalFilesDspPanel.subTypeComboBox.localFilesOption.text=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u30fc
-Menu/Case/OpenRecentCase=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
MissingImageDialog.ErrorSettingImage=\u30a4\u30e1\u30fc\u30b8\u30d1\u30b9\u306e\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002
MissingImageDialog.browseButton.text=\u53c2\u7167
MissingImageDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
@@ -313,7 +332,7 @@ NewCaseVisualPanel1.CaseFolderOnCDriveError.text=\u8b66\u544a\: \u30de\u30eb\u30
NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=\u8b66\u544a\: \u30b1\u30fc\u30b9\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u30d1\u30b9\u306f\u30bf\u30fc\u30b2\u30c3\u30c8\u30b7\u30b9\u30c6\u30e0\u4e0a\u306b\u3042\u308a\u307e\u3059\u3002\u30de\u30a6\u30f3\u30c8\u3055\u308c\u305f\u30c9\u30e9\u30a4\u30d6\u5185\u306b\u30b1\u30fc\u30b9\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=\u8b66\u544a\: \u30b1\u30fc\u30b9\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u30d1\u30b9\u306f "C\:" \u30c9\u30e9\u30a4\u30d6\u306b\u3042\u308a\u307e\u3059\u3002\u30b1\u30fc\u30b9\u30d5\u30a9\u30eb\u30c0\u30fc\u306f\u30bf\u30fc\u30b2\u30c3\u30c8\u30b7\u30b9\u30c6\u30e0\u4e0a\u306b\u4f5c\u6210\u3055\u308c\u307e\u3059
NewCaseVisualPanel1.badCredentials.text=\u4e0d\u6b63\u306a\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u8a2d\u5b9a(\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167)\u304b\u3001\u30b5\u30fc\u30d3\u30b9\u304c\u30c0\u30a6\u30f3\u3057\u3066\u3044\u307e\u3059\u3002
-NewCaseVisualPanel1.caseDataStoredLabel.text_1=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u306f\u6b21\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059\uff1a
+NewCaseVisualPanel1.caseDataStoredLabel.text_1=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u306f\u6b21\u306e\u30d5\u30a9\u30eb\u30c0\u30fc\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059\uff1a
NewCaseVisualPanel1.caseDirBrowse.selectButton.text=\u9078\u629e
NewCaseVisualPanel1.caseDirBrowseButton.text=\u53c2\u7167
NewCaseVisualPanel1.caseDirLabel.text=\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\:
@@ -324,8 +343,9 @@ NewCaseVisualPanel1.caseParentDirTextField.text=
NewCaseVisualPanel1.caseParentDirWarningLabel.text=
NewCaseVisualPanel1.caseTypeLabel.text=\u30b1\u30fc\u30b9\u30bf\u30a4\u30d7\:
NewCaseVisualPanel1.getName.text=\u30b1\u30fc\u30b9\u60c5\u5831
-NewCaseVisualPanel1.multiUserCaseRadioButton.text=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\t\t
+NewCaseVisualPanel1.multiUserCaseRadioButton.text=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc
NewCaseVisualPanel1.singleUserCaseRadioButton.text=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc
+NewCaseVisualPanel1.uncPath.error=\u30a8\u30e9\u30fc\uff1a\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u306e\u5834\u5408\u3001UNC\u30d1\u30b9\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093
NewCaseVisualPanel2.getName.text=\u4efb\u610f\u60c5\u5831
NewCaseWizardAction.databaseProblem1.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u306e\u4f5c\u6210\u3092\u53d6\u308a\u6d88\u3057\u4e2d\u3067\u3059\u3002
NewCaseWizardAction.databaseProblem2.text=\u30a8\u30e9\u30fc
@@ -348,6 +368,7 @@ OpenMultiUserCaseDialog.title=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u
OpenMultiUserCasePanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
OpenMultiUserCasePanel.openSelectedCaseButton.text=\u9078\u629e\u3057\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
OpenMultiUserCasePanel.openSingleUserCaseButton.tex=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u304f...
+OpenMultiUserCasePanel.openSingleUserCaseButton.text=\u5358\u72ec\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u304f...
OpenMultiUserCasePanel.searchLabel.text=\u4efb\u610f\u306e\u30b1\u30fc\u30b9\u3092\u9078\u629e\u3057\u3001\u5165\u529b\u3092\u958b\u59cb\u3057\u3066\u30b1\u30fc\u30b9\u540d\u3067\u691c\u7d22
OpenRecentCasePanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
OpenRecentCasePanel.colName.caseName=\u30b1\u30fc\u30b9\u540d
@@ -383,13 +404,20 @@ ReviewModeCasePanel.StatusIconHeaderText=\u30b9\u30c6\u30fc\u30bf\u30b9
ReviewModeCasePanel.cannotOpenCase=\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093
ReviewModeCasePanel.caseIsLocked=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002
ReviewModeCasePanel.casePathNotFound=\u30b1\u30fc\u30b9\u30d1\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
-SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u8ffd\u52a0
+SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u9078\u629e
SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u3059\u3067\u306b\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u3067\u3059\!
SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\!
SingleUserCaseConverter.CanNotOpenDatabase=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093
SingleUserCaseConverter.NonUniqueDatabaseName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\u304c\u4e00\u610f\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
SingleUserCaseConverter.UnableToCopySourceImages=\u30bd\u30fc\u30b9\u30a4\u30e1\u30fc\u30b8\u3092\u30b3\u30d4\u30fc\u3067\u304d\u307e\u305b\u3093
+SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr8\u63a5\u7d9a\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 [\u30c4\u30fc\u30eb]-> [\u30aa\u30d7\u30b7\u30e7\u30f3]-> [\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc]\u306b\u79fb\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+SolrNotConfiguredDialog.messageLabel.text=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u306f\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u304c\u3001Solr8\u30b5\u30fc\u30d0\u30fc\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
\n\u65b0\u3057\u3044\u30b1\u30fc\u30b9\u306fSolr8\u3067\u306e\u307f\u4f5c\u6210\u3067\u304d\u307e\u3059\u3002[\u30c4\u30fc\u30eb]-> [\u30aa\u30d7\u30b7\u30e7\u30f3]-> [\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc]\u306b\u79fb\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+SolrNotConfiguredDialog.okButton.text=OK
+SolrNotConfiguredDialog.title=Solr8\u30b5\u30fc\u30d0\u30fc\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
StartupWindow.title.text=\u3088\u3046\u3053\u305d
+StartupWindowProvider.openCase.cantOpen=\u4ee5\u524d\u306b\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb{0}\u3067\u958b\u304f\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002
+StartupWindowProvider.openCase.deleteOpenFailure=\u4ee5\u524d\u306b\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3078\u306e\u30d1\u30b9{0}\u3092\u542b\u3080\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u3044\u305f\u308a\u524a\u9664\u3057\u305f\u308a\u3067\u304d\u307e\u305b\u3093\u3002 \u524d\u306e\u30b1\u30fc\u30b9\u306f\u958b\u304b\u308c\u307e\u305b\u3093\u3002
+StartupWindowProvider.openCase.noFile=\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u304c{0}\u306b\u898b\u3064\u304b\u3089\u306a\u3044\u305f\u3081\u3001\u4ee5\u524d\u306b\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002
UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=\u30dd\u30fc\u30bf\u30d6\u30eb\u30b1\u30fc\u30b9\u30d1\u30c3\u30b1\u30fc\u30b8(.zip, .zip.001)
UnpackagePortableCaseDialog.caseErrorLabel.text=jLabel1
UnpackagePortableCaseDialog.caseLabel.text=\u30dd\u30fc\u30bf\u30d6\u30eb\u30b1\u30fc\u30b9\:
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index 4347c0d778..6f10bcf364 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2012-2020 Basis Technology Corp.
+ * Copyright 2012-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils;
import com.google.common.annotations.Beta;
import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.awt.Cursor;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
import java.awt.Frame;
import java.awt.event.ActionEvent;
@@ -29,6 +30,7 @@ import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
+import java.lang.reflect.InvocationTargetException;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -39,6 +41,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -61,6 +64,7 @@ import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
+import org.apache.commons.lang3.StringUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
@@ -81,7 +85,24 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
import org.sleuthkit.autopsy.casemodule.events.DataSourceDeletedEvent;
import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent;
+import org.sleuthkit.autopsy.casemodule.events.HostsAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.HostsAddedToPersonEvent;
+import org.sleuthkit.autopsy.casemodule.events.HostsUpdatedEvent;
+import org.sleuthkit.autopsy.casemodule.events.HostsDeletedEvent;
+import org.sleuthkit.autopsy.casemodule.events.HostsRemovedFromPersonEvent;
+import org.sleuthkit.autopsy.casemodule.events.OsAccountsAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.OsAccountsUpdatedEvent;
+import org.sleuthkit.autopsy.casemodule.events.OsAccountsDeletedEvent;
+import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.PersonsAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.PersonsUpdatedEvent;
+import org.sleuthkit.autopsy.casemodule.events.PersonsDeletedEvent;
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesDeletedEvent;
+import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesUpdatedEvent;
+import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsAddedEvent;
+import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsDeletedEvent;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData.CaseNodeDataException;
import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils;
import org.sleuthkit.autopsy.casemodule.services.Services;
@@ -104,6 +125,8 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.ThreadUtils;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.coreutils.Version;
+import org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction;
+import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.events.AutopsyEventException;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
@@ -114,6 +137,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
+import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
import org.sleuthkit.autopsy.progress.LoggingProgressIndicator;
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
@@ -127,13 +151,17 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.FileSystem;
+import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Image;
+import org.sleuthkit.datamodel.OsAccount;
+import org.sleuthkit.datamodel.Person;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TimelineManager;
import org.sleuthkit.datamodel.SleuthkitCaseAdminUtil;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
+import org.sleuthkit.datamodel.TskEvent;
import org.sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
/**
@@ -141,9 +169,10 @@ import org.sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
*/
public class Case {
- private static final String CASE_TEMP_DIR = Case.class.getSimpleName();
private static final int CASE_LOCK_TIMEOUT_MINS = 1;
private static final int CASE_RESOURCES_LOCK_TIMEOUT_HOURS = 1;
+ private static final String APP_NAME = UserPreferences.getAppName();
+ private static final String TEMP_FOLDER = "Temp";
private static final String SINGLE_USER_CASE_DB_NAME = "autopsy.db";
private static final String EVENT_CHANNEL_NAME = "%s-Case-Events"; //NON-NLS
private static final String CACHE_FOLDER = "Cache"; //NON-NLS
@@ -171,6 +200,9 @@ public class Case {
private CollaborationMonitor collaborationMonitor;
private Services caseServices;
+ private volatile boolean hasDataSource = false;
+ private volatile boolean hasData = false;
+
/*
* Get a reference to the main window of the desktop application to use to
* parent pop up dialogs and initialize the application name for use in
@@ -409,7 +441,80 @@ public class Case {
* An item in the central repository has had its comment modified. The
* old value is null, the new value is string for current comment.
*/
- CR_COMMENT_CHANGED;
+ CR_COMMENT_CHANGED,
+ /**
+ * One or more OS accounts have been added to the case.
+ */
+ OS_ACCOUNTS_ADDED,
+ /**
+ * One or more OS accounts in the case have been updated.
+ */
+ OS_ACCOUNTS_UPDATED,
+ /**
+ * One or more OS accounts have been deleted from the case.
+ */
+ OS_ACCOUNTS_DELETED,
+ /**
+ * One or more OS account instances have been added to the case.
+ */
+ OS_ACCT_INSTANCES_ADDED,
+ /**
+ * One or more hosts have been added to the case.
+ */
+ HOSTS_ADDED,
+ /**
+ * One or more hosts in the case have been updated.
+ */
+ HOSTS_UPDATED,
+ /**
+ * One or more hosts have been deleted from the case.
+ */
+ HOSTS_DELETED,
+ /**
+ * One or more persons have been added to the case.
+ */
+ PERSONS_ADDED,
+ /**
+ * One or more persons in the case have been updated.
+ */
+ PERSONS_UPDATED,
+ /**
+ * One or more persons been deleted from the case.
+ */
+ PERSONS_DELETED,
+ /**
+ * One or more hosts have been added to a person.
+ */
+ HOSTS_ADDED_TO_PERSON,
+ /**
+ * One or more hosts have been removed from a person.
+ */
+ HOSTS_REMOVED_FROM_PERSON,
+
+ /**
+ * One or more TagNames have been added.
+ */
+ TAG_NAMES_ADDED,
+
+ /**
+ * One or more TagNames have been updated.
+ */
+ TAG_NAMES_UPDATED,
+
+ /**
+ * One or more TagNames have been deleted.
+ */
+ TAG_NAMES_DELETED,
+
+ /**
+ * One or more TagSets have been added.
+ */
+ TAG_SETS_ADDED,
+
+ /**
+ * One or more TagSets have been removed.
+ */
+ TAG_SETS_DELETED;
};
@@ -425,23 +530,138 @@ public class Case {
eventPublisher.publish(new TimelineEventAddedEvent(event));
}
- @SuppressWarnings("deprecation")
@Subscribe
- public void publishArtifactsPostedEvent(Blackboard.ArtifactsPostedEvent event) {
- for (BlackboardArtifact.Type artifactType : event.getArtifactTypes()) {
- /*
- * IngestServices.fireModuleDataEvent is deprecated to
- * discourage ingest module writers from using it (they should
- * use org.sleuthkit.datamodel.Blackboard.postArtifact(s)
- * instead), but a way to publish
- * Blackboard.ArtifactsPostedEvents from the SleuthKit layer as
- * Autopsy ModuleDataEvents is still needed.
- */
- IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(
- event.getModuleName(),
- artifactType,
- event.getArtifacts(artifactType)));
+ public void publishOsAccountsAddedEvent(TskEvent.OsAccountsAddedTskEvent event) {
+ hasData = true;
+ eventPublisher.publish(new OsAccountsAddedEvent(event.getOsAcounts()));
+ }
+
+ @Subscribe
+ public void publishOsAccountsUpdatedEvent(TskEvent.OsAccountsUpdatedTskEvent event) {
+ eventPublisher.publish(new OsAccountsUpdatedEvent(event.getOsAcounts()));
+ }
+
+ @Subscribe
+ public void publishOsAccountDeletedEvent(TskEvent.OsAccountsDeletedTskEvent event) {
+ try {
+ hasData = dbHasData();
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
}
+ eventPublisher.publish(new OsAccountsDeletedEvent(event.getOsAccountObjectIds()));
+ }
+
+ @Subscribe
+ public void publishOsAccountInstancesAddedEvent(TskEvent.OsAcctInstancesAddedTskEvent event) {
+ eventPublisher.publish(new OsAcctInstancesAddedEvent(event.getOsAccountInstances()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit HostAddedEvent
+ * indicating that hosts have been created.
+ *
+ * @param event The sleuthkit event for the creation of hosts.
+ */
+ @Subscribe
+ public void publishHostsAddedEvent(TskEvent.HostsAddedTskEvent event) {
+ hasData = true;
+ eventPublisher.publish(new HostsAddedEvent(event.getHosts()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit HostUpdateEvent
+ * indicating that hosts have been updated.
+ *
+ * @param event The sleuthkit event for the updating of hosts.
+ */
+ @Subscribe
+ public void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event) {
+ eventPublisher.publish(new HostsUpdatedEvent(event.getHosts()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit HostDeletedEvent
+ * indicating that hosts have been deleted.
+ *
+ * @param event The sleuthkit event for the deleting of hosts.
+ */
+ @Subscribe
+ public void publishHostsDeletedEvent(TskEvent.HostsDeletedTskEvent event) {
+ try {
+ hasData = dbHasData();
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
+ }
+
+ eventPublisher.publish(new HostsDeletedEvent(event.getHostIds()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit PersonAddedEvent
+ * indicating that persons have been created.
+ *
+ * @param event The sleuthkit event for the creation of persons.
+ */
+ @Subscribe
+ public void publishPersonsAddedEvent(TskEvent.PersonsAddedTskEvent event) {
+ eventPublisher.publish(new PersonsAddedEvent(event.getPersons()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit PersonChangedEvent
+ * indicating that persons have been updated.
+ *
+ * @param event The sleuthkit event for the updating of persons.
+ */
+ @Subscribe
+ public void publishPersonsUpdatedEvent(TskEvent.PersonsUpdatedTskEvent event) {
+ eventPublisher.publish(new PersonsUpdatedEvent(event.getPersons()));
+ }
+
+ /**
+ * Publishes an autopsy event from the sleuthkit PersonDeletedEvent
+ * indicating that persons have been deleted.
+ *
+ * @param event The sleuthkit event for the deleting of persons.
+ */
+ @Subscribe
+ public void publishPersonsDeletedEvent(TskEvent.PersonsDeletedTskEvent event) {
+ eventPublisher.publish(new PersonsDeletedEvent(event.getPersonIds()));
+ }
+
+ @Subscribe
+ public void publishHostsAddedToPersonEvent(TskEvent.HostsAddedToPersonTskEvent event) {
+ eventPublisher.publish(new HostsAddedToPersonEvent(event.getPerson(), event.getHosts()));
+ }
+
+ @Subscribe
+ public void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event) {
+ eventPublisher.publish(new HostsRemovedFromPersonEvent(event.getPerson(), event.getHostIds()));
+ }
+
+ @Subscribe
+ public void publicTagNamesAdded(TskEvent.TagNamesAddedTskEvent event) {
+ eventPublisher.publish(new TagNamesAddedEvent(event.getTagNames()));
+ }
+
+ @Subscribe
+ public void publicTagNamesUpdated(TskEvent.TagNamesUpdatedTskEvent event) {
+ eventPublisher.publish(new TagNamesUpdatedEvent(event.getTagNames()));
+ }
+
+ @Subscribe
+ public void publicTagNamesDeleted(TskEvent.TagNamesDeletedTskEvent event) {
+ eventPublisher.publish(new TagNamesDeletedEvent(event.getTagNameIds()));
+ }
+
+ @Subscribe
+ public void publicTagSetsAdded(TskEvent.TagSetsAddedTskEvent event) {
+ eventPublisher.publish(new TagSetsAddedEvent(event.getTagSets()));
+ }
+
+ @Subscribe
+ public void publicTagSetsDeleted(TskEvent.TagSetsDeletedTskEvent event) {
+ eventPublisher.publish(new TagSetsDeletedEvent(event.getTagSetIds()));
}
}
@@ -720,13 +940,13 @@ public class Case {
try {
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), closedCase, null));
logger.log(Level.INFO, "Closing current case {0} ({1}) in {2}", new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); //NON-NLS
- currentCase = null;
closedCase.doCloseCaseAction();
logger.log(Level.INFO, "Closed current case {0} ({1}) in {2}", new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); //NON-NLS
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error closing current case %s (%s) in %s", closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()), ex); //NON-NLS
throw ex;
} finally {
+ currentCase = null;
if (RuntimeProperties.runningWithGUI()) {
updateGUIForCaseClosed();
}
@@ -1066,88 +1286,106 @@ public class Case {
* Update the GUI to to reflect the current case.
*/
private static void updateGUIForCaseOpened(Case newCurrentCase) {
- if (RuntimeProperties.runningWithGUI()) {
- SwingUtilities.invokeLater(() -> {
- /*
- * If the case database was upgraded for a new schema and a
- * backup database was created, notify the user.
- */
- SleuthkitCase caseDb = newCurrentCase.getSleuthkitCase();
- String backupDbPath = caseDb.getBackupDatabasePath();
- if (null != backupDbPath) {
- JOptionPane.showMessageDialog(
- mainFrame,
- NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", backupDbPath),
- NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
- JOptionPane.INFORMATION_MESSAGE);
- }
-
- /*
- * Look for the files for the data sources listed in the case
- * database and give the user the opportunity to locate any that
- * are missing.
- */
- Map imgPaths = getImagePaths(caseDb);
- for (Map.Entry entry : imgPaths.entrySet()) {
- long obj_id = entry.getKey();
- String path = entry.getValue();
- boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path));
- if (!fileExists) {
- int response = JOptionPane.showConfirmDialog(
- mainFrame,
- NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path),
- NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"),
- JOptionPane.YES_NO_OPTION);
- if (response == JOptionPane.YES_OPTION) {
- MissingImageDialog.makeDialog(obj_id, caseDb);
- } else {
- logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS
-
- }
- }
- }
-
- /*
- * Enable the case-specific actions.
- */
- CallableSystemAction.get(AddImageAction.class).setEnabled(FeatureAccessUtils.canAddDataSources());
- CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
- CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true);
- CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true);
- CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCurrentCase());
- CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
- CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
- CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
- CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
- CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true);
-
- /*
- * Add the case to the recent cases tracker that supplies a list
- * of recent cases to the recent cases menu item and the
- * open/create case dialog.
- */
- RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString());
-
- /*
- * Open the top components (windows within the main application
- * window).
- *
- * Note: If the core windows are not opened here, they will be
- * opened via the DirectoryTreeTopComponent 'propertyChange()'
- * method on a DATA_SOURCE_ADDED event.
- */
- if (newCurrentCase.hasData()) {
- CoreComponentControl.openCoreWindows();
- }
-
- /*
- * Reset the main window title to:
- *
- * [curent case display name] - [application name].
- */
- mainFrame.setTitle(newCurrentCase.getDisplayName() + " - " + getNameForTitle());
- });
+ /*
+ * If the case database was upgraded for a new schema and a backup
+ * database was created, notify the user.
+ */
+ SleuthkitCase caseDb = newCurrentCase.getSleuthkitCase();
+ String backupDbPath = caseDb.getBackupDatabasePath();
+ if (null != backupDbPath) {
+ JOptionPane.showMessageDialog(
+ mainFrame,
+ NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", backupDbPath),
+ NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
+ JOptionPane.INFORMATION_MESSAGE);
}
+
+ /*
+ * Look for the files for the data sources listed in the case database
+ * and give the user the opportunity to locate any that are missing.
+ */
+ Map imgPaths = getImagePaths(caseDb);
+ for (Map.Entry entry : imgPaths.entrySet()) {
+ long obj_id = entry.getKey();
+ String path = entry.getValue();
+ boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path));
+ if (!fileExists) {
+ try {
+ // Using invokeAndWait means that the dialog will
+ // open on the EDT but this thread will wait for an
+ // answer. Using invokeLater would cause this loop to
+ // end before all of the dialogs appeared.
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ int response = JOptionPane.showConfirmDialog(
+ mainFrame,
+ NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path),
+ NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"),
+ JOptionPane.YES_NO_OPTION);
+ if (response == JOptionPane.YES_OPTION) {
+ MissingImageDialog.makeDialog(obj_id, caseDb);
+ } else {
+ logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS
+
+ }
+ }
+
+ });
+ } catch (InterruptedException | InvocationTargetException ex) {
+ logger.log(Level.SEVERE, "Failed to show missing image confirmation dialog", ex); //NON-NLS
+ }
+ }
+ }
+
+ /*
+ * Enable the case-specific actions.
+ */
+ CallableSystemAction.get(AddImageAction.class).setEnabled(FeatureAccessUtils.canAddDataSources());
+ CallableSystemAction.get(OpenHostsAction.class).setEnabled(true);
+ CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
+ CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true);
+ CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true);
+ CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCurrentCase());
+ CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
+ CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
+ CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
+ CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
+ CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true);
+
+ /*
+ * Add the case to the recent cases tracker that supplies a list of
+ * recent cases to the recent cases menu item and the open/create case
+ * dialog.
+ */
+ RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString());
+ final boolean hasData = newCurrentCase.hasData();
+
+ SwingUtilities.invokeLater(() -> {
+ /*
+ * Open the top components (windows within the main application
+ * window).
+ *
+ * Note: If the core windows are not opened here, they will be
+ * opened via the DirectoryTreeTopComponent 'propertyChange()'
+ * method on a DATA_SOURCE_ADDED event.
+ */
+ mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ if (hasData) {
+ CoreComponentControl.openCoreWindows();
+ } else {
+ //ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible.
+ DirectoryTreeTopComponent.findInstance();
+ }
+ mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+
+ /*
+ * Reset the main window title to:
+ *
+ * [curent case display name] - [application name].
+ */
+ mainFrame.setTitle(newCurrentCase.getDisplayName() + " - " + getNameForTitle());
+ });
}
/*
@@ -1166,6 +1404,7 @@ public class Case {
* Disable the case-specific menu items.
*/
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
+ CallableSystemAction.get(OpenHostsAction.class).setEnabled(false);
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false);
CallableSystemAction.get(CaseDetailsAction.class).setEnabled(false);
CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(false);
@@ -1321,6 +1560,13 @@ public class Case {
return hostPath.toString();
}
+ /**
+ * @return A subdirectory of java.io.tmpdir.
+ */
+ private Path getBaseSystemTempPath() {
+ return Paths.get(System.getProperty("java.io.tmpdir"), APP_NAME, getName());
+ }
+
/**
* Gets the full path to the temp directory for this case, creating it if it
* does not exist.
@@ -1328,16 +1574,45 @@ public class Case {
* @return The temp subdirectory path.
*/
public String getTempDirectory() {
- // get temp folder scoped to the combination of case name and timestamp
- // provided by getName()
- Path path = Paths.get(UserPreferences.getAppTempDirectory(), CASE_TEMP_DIR, getName());
- File f = path.toFile();
- // verify that the folder exists
- if (!f.exists()) {
- f.mkdirs();
+ // NOTE: UserPreferences may also be affected by changes in this method.
+ // See JIRA-7505 for more information.
+ Path basePath = null;
+ // get base temp path for the case based on user preference
+ switch (UserMachinePreferences.getTempDirChoice()) {
+ case CUSTOM:
+ String customDirectory = UserMachinePreferences.getCustomTempDirectory();
+ basePath = (StringUtils.isBlank(customDirectory))
+ ? null
+ : Paths.get(customDirectory, APP_NAME, getName());
+ break;
+ case CASE:
+ basePath = Paths.get(getCaseDirectory());
+ break;
+ case SYSTEM:
+ default:
+ // at this level, if the case directory is specified for a temp
+ // directory, return the system temp directory instead.
+ basePath = getBaseSystemTempPath();
+ break;
}
- return path.toAbsolutePath().toString();
+ basePath = basePath == null ? getBaseSystemTempPath() : basePath;
+
+ // get sub directories based on multi user vs. single user
+ Path caseRelPath = (CaseType.MULTI_USER_CASE.equals(getCaseType()))
+ ? Paths.get(NetworkUtils.getLocalHostName(), TEMP_FOLDER)
+ : Paths.get(TEMP_FOLDER);
+
+ File caseTempDir = basePath
+ .resolve(caseRelPath)
+ .toFile();
+
+ // ensure directory exists
+ if (!caseTempDir.exists()) {
+ caseTempDir.mkdirs();
+ }
+
+ return caseTempDir.getAbsolutePath();
}
/**
@@ -1462,26 +1737,21 @@ public class Case {
}
/**
- * Queries whether or not the case has data, i.e., whether or not at least
- * one data source has been added to the case.
+ * Returns true if there is any data in the case.
*
* @return True or false.
*/
public boolean hasData() {
- boolean hasDataSources = false;
- String query = "SELECT count(*) AS count FROM data_source_info";
- try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
- ResultSet resultSet = dbQuery.getResultSet();
- if (resultSet.next()) {
- long numDataSources = resultSet.getLong("count");
- if (numDataSources > 0) {
- hasDataSources = true;
- }
- }
- } catch (TskCoreException | SQLException ex) {
- logger.log(Level.SEVERE, "Error accessing case database", ex); //NON-NLS
- }
- return hasDataSources;
+ return hasData;
+ }
+
+ /**
+ * Returns true if there is one or more data sources in the case.
+ *
+ * @return True or false.
+ */
+ public boolean hasDataSource() {
+ return hasDataSource;
}
/**
@@ -1495,6 +1765,8 @@ public class Case {
* notifyNewDataSource after the data source is added.
*/
public void notifyAddingDataSource(UUID eventId) {
+ hasDataSource = true;
+ hasData = true;
eventPublisher.publish(new AddingDataSourceEvent(eventId));
}
@@ -1681,6 +1953,8 @@ public class Case {
String errorMsg = "Invalid local path provided: " + localPath; // NON-NLS
throw new TskCoreException(errorMsg, ex);
}
+ hasData = true;
+
Report report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
eventPublisher.publish(new ReportAddedEvent(report));
return report;
@@ -1709,6 +1983,15 @@ public class Case {
public void deleteReports(Collection extends Report> reports) throws TskCoreException {
for (Report report : reports) {
this.caseDb.deleteReport(report);
+ }
+
+ try {
+ hasData = dbHasData();
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
+ }
+
+ for (Report report : reports) {
eventPublisher.publish(new AutopsyEvent(Events.REPORT_DELETED.toString(), report, null));
}
}
@@ -1718,7 +2001,7 @@ public class Case {
*
* @return A CaseMetaData object.
*/
- CaseMetadata getMetadata() {
+ public CaseMetadata getMetadata() {
return metadata;
}
@@ -2466,6 +2749,7 @@ public class Case {
} else {
throw new CaseActionException(Bundle.Case_open_exception_multiUserCaseNotEnabled());
}
+ updateDataParameters();
} catch (TskUnsupportedSchemaVersionException ex) {
throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
} catch (UserPreferencesException ex) {
@@ -2828,8 +3112,8 @@ public class Case {
* @throws CaseActionException If the lock cannot be acquired.
*/
@Messages({
- "Case.lockingException.couldNotAcquireSharedLock=Failed to get an shared lock on the case.",
- "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get a exclusive lock on the case."
+ "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
+ "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case."
})
private void acquireCaseLock(CaseLockType lockType) throws CaseActionException {
String caseDir = metadata.getCaseDirectory();
@@ -3243,6 +3527,78 @@ public class Case {
}
}
+ /**
+ * Initialize the hasData and hasDataSource parameters by checking the
+ * database.
+ *
+ * hasDataSource will be true if any data Source exists the db.
+ *
+ * hasData will be true if hasDataSource is true or if there are entries in
+ * the tsk_object or tsk_host tables.
+ *
+ * @throws TskCoreException
+ */
+ private void updateDataParameters() throws TskCoreException {
+ hasDataSource = dbHasDataSource();
+
+ if (!hasDataSource) {
+ hasData = dbHasData();
+ } else {
+ hasData = true;
+ }
+ }
+
+ /**
+ * Returns true of there are any data sources in the case database.
+ *
+ * @return True if this case as a data source.
+ *
+ * @throws TskCoreException
+ */
+ private boolean dbHasDataSource() throws TskCoreException {
+ String query = "SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
+ try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
+ ResultSet resultSet = dbQuery.getResultSet();
+ if (resultSet.next()) {
+ return resultSet.getLong("count") > 0;
+ }
+ return false;
+ } catch (SQLException ex) {
+ logger.log(Level.SEVERE, "Error accessing case database", ex); //NON-NLS
+ throw new TskCoreException("Error accessing case databse", ex);
+ }
+ }
+
+ /**
+ * Returns true if the case has data. A case has data if there is at least
+ * one row in either the tsk_objects or tsk_hosts table.
+ *
+ * @return True if there is data in this case.
+ *
+ * @throws TskCoreException
+ */
+ private boolean dbHasData() throws TskCoreException {
+ // The LIMIT 1 in the subquery should limit the data returned and
+ // make the overall query more efficent.
+ String query = "SELECT SUM(cnt) total FROM "
+ + "(SELECT COUNT(*) AS cnt FROM "
+ + "(SELECT * FROM tsk_objects LIMIT 1)t "
+ + "UNION ALL "
+ + "SELECT COUNT(*) AS cnt FROM "
+ + "(SELECT * FROM tsk_hosts LIMIT 1)r) s";
+ try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
+ ResultSet resultSet = dbQuery.getResultSet();
+ if (resultSet.next()) {
+ return resultSet.getLong("total") > 0;
+ } else {
+ return false;
+ }
+ } catch (SQLException ex) {
+ logger.log(Level.SEVERE, "Error accessing case database", ex); //NON-NLS
+ throw new TskCoreException("Error accessing case databse", ex);
+ }
+ }
+
/**
* Defines the signature for case action methods that can be passed as
* arguments to the doCaseAction method.
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
index 5f7ffe9ea7..96f9899dae 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
@@ -218,7 +218,7 @@ public final class CaseMetadata {
*
* @return The path to the metadata file
*/
- Path getFilePath() {
+ public Path getFilePath() {
return metadataFilePath;
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
index 0ba92c7bce..25789939b3 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2017 Basis Technology Corp.
+ * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,6 +43,7 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.Version;
+import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
/**
* The action associated with the Case/Open Case menu item via the layer.xml
@@ -64,6 +65,8 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
private static final Logger LOGGER = Logger.getLogger(CaseOpenAction.class.getName());
private final FileFilter caseMetadataFileFilter;
+ private final JFileChooserFactory fileChooserHelper;
+
/**
* Constructs the action associated with the Case/Open Case menu item via
* the layer.xml file, a toolbar button, and the Open Case button of the
@@ -72,6 +75,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
*/
public CaseOpenAction() {
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1));
+ fileChooserHelper = new JFileChooserFactory();
}
/**
@@ -80,7 +84,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
* to open the case described by the file.
*/
void openCaseSelectionWindow() {
- JFileChooser fileChooser = new JFileChooser();
+ JFileChooser fileChooser = fileChooserHelper.getChooser();
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java
index 9967f1fb68..8f749199f7 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java
@@ -35,22 +35,22 @@ import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
* Read and update case preference file values.
*/
public final class CasePreferences {
-
+
private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS
private static final String KEY_GROUP_BY_DATA_SOURCE = "groupByDataSource"; //NON-NLS
private static final String VALUE_TRUE = "true"; //NON-NLS
private static final String VALUE_FALSE = "false"; //NON-NLS
-
+
private static final Logger logger = Logger.getLogger(CasePreferences.class.getName());
-
+
private static Boolean groupItemsInTreeByDataSource = false;
-
+
/**
* Prevent instantiation.
*/
private CasePreferences() {
}
-
+
static {
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
if (evt.getNewValue() != null) {
@@ -66,25 +66,27 @@ public final class CasePreferences {
logger.log(Level.SEVERE, "No current case open.", ex);
}
}
-
+
/**
* Get the 'groupItemsInTreeByDataSource' value. This can be true, false, or
* null.
- *
+ *
* @return The value.
*/
public static Boolean getGroupItemsInTreeByDataSource() {
return groupItemsInTreeByDataSource;
}
-
+
/**
* Set the 'groupItemsInTreeByDataSource' value to true or false.
- *
+ *
* @param value The value to use for the value change.
*/
public static void setGroupItemsInTreeByDataSource(boolean value) {
groupItemsInTreeByDataSource = value;
- DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
+ if (Case.isCaseOpen()) {
+ DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
+ }
}
/**
@@ -120,7 +122,7 @@ public final class CasePreferences {
}
}
}
-
+
/**
* Reset all values to their default states.
*/
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java b/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java
index e6a7772c73..ec5fd85782 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2019 Basis Technology Corp.
+ * Copyright 2015-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -237,7 +237,7 @@ final class CollaborationMonitor {
Content dataSource = event.getDataSource();
if (dataSource != null) {
String status = NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.analyzingDataSourceStatus.msg", hostName, dataSource.getName());
- jobIdsTodataSourceAnalysisTasks.put(event.getDataSourceIngestJobId(), new Task(++nextTaskId, status));
+ jobIdsTodataSourceAnalysisTasks.put(event.getIngestJobId(), new Task(++nextTaskId, status));
eventPublisher.publishRemotely(new CollaborationEvent(hostName, getCurrentTasks()));
}
}
@@ -250,7 +250,7 @@ final class CollaborationMonitor {
* @param event A data source analysis completed event.
*/
synchronized void removeDataSourceAnalysisTask(DataSourceAnalysisCompletedEvent event) {
- jobIdsTodataSourceAnalysisTasks.remove(event.getDataSourceIngestJobId());
+ jobIdsTodataSourceAnalysisTasks.remove(event.getIngestJobId());
eventPublisher.publishRemotely(new CollaborationEvent(hostName, getCurrentTasks()));
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
index 207b83ed8a..9b174f28f7 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2013-2018 Basis Technology Corp.
+ * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestStream;
+import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitJNI;
import org.sleuthkit.datamodel.TskCoreException;
@@ -50,8 +51,7 @@ import org.sleuthkit.datamodel.TskCoreException;
* independently of the wizard.
*/
@ServiceProviders(value = {
- @ServiceProvider(service = DataSourceProcessor.class)
- ,
+ @ServiceProvider(service = DataSourceProcessor.class),
@ServiceProvider(service = AutoIngestDataSourceProcessor.class)}
)
public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSourceProcessor {
@@ -81,7 +81,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
private String md5;
private String sha1;
private String sha256;
- private boolean setDataSourceOptionsCalled;
+ private Host host = null;
static {
filtersList.add(allFilter);
@@ -181,50 +181,96 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
- ingestStream = new DefaultIngestStream();
- readConfigSettings();
- try {
- image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId);
- } catch (TskCoreException ex) {
- logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
- final List errors = new ArrayList<>();
- errors.add(ex.getMessage());
- callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
- return;
- }
-
- doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, progressMonitor, callback);
+ run(null, progressMonitor, callback);
}
-
+
/**
* Adds a data source to the case database using a background task in a
* separate thread and the settings provided by the selection and
- * configuration panel. Files found during ingest will be sent directly to the
- * IngestStream provided. Returns as soon as the background task is started.
+ * configuration panel. Returns as soon as the background task is started.
* The background task uses a callback object to signal task completion and
* return results.
*
- * This method should not be called unless isPanelValid returns true, and
- * should only be called for DSPs that support ingest streams.
- *
- * @param settings The ingest job settings.
- * @param progress Progress monitor that will be used by the
+ * This method should not be called unless isPanelValid returns true.
+ *
+ * @param host Host for this data source.
+ * @param progressMonitor Progress monitor that will be used by the
* background task to report progress.
- * @param callBack Callback that will be used by the background task
+ * @param callback Callback that will be used by the background task
* to return results.
*/
@Override
- public void runWithIngestStream(IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
+ public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
+ ingestStream = new DefaultIngestStream();
+ readConfigSettings();
+ this.host = host;
+ try {
+ image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host);
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
+ final List errors = new ArrayList<>();
+ errors.add(ex.getMessage());
+ callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
+ return;
+ }
+
+ doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, progressMonitor, callback);
+ }
+
+ /**
+ * Adds a data source to the case database using a background task in a
+ * separate thread and the settings provided by the selection and
+ * configuration panel. Files found during ingest will be sent directly to
+ * the IngestStream provided. Returns as soon as the background task is
+ * started. The background task uses a callback object to signal task
+ * completion and return results.
+ *
+ * This method should not be called unless isPanelValid returns true, and
+ * should only be called for DSPs that support ingest streams.
+ *
+ * @param settings The ingest job settings.
+ * @param progress Progress monitor that will be used by the background task
+ * to report progress.
+ * @param callBack Callback that will be used by the background task to
+ * return results.
+ */
+ @Override
+ public void runWithIngestStream(IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
DataSourceProcessorCallback callBack) {
-
+ runWithIngestStream(null, settings, progress, callBack);
+ }
+
+ /**
+ * Adds a data source to the case database using a background task in a
+ * separate thread and the settings provided by the selection and
+ * configuration panel. Files found during ingest will be sent directly to
+ * the IngestStream provided. Returns as soon as the background task is
+ * started. The background task uses a callback object to signal task
+ * completion and return results.
+ *
+ * This method should not be called unless isPanelValid returns true, and
+ * should only be called for DSPs that support ingest streams.
+ *
+ * @param host The host for this data source.
+ * @param settings The ingest job settings.
+ * @param progress Progress monitor that will be used by the background task
+ * to report progress.
+ * @param callBack Callback that will be used by the background task to
+ * return results.
+ */
+ @Override
+ public void runWithIngestStream(Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
+ DataSourceProcessorCallback callBack) {
+
// Read the settings from the wizard
readConfigSettings();
-
+ this.host = host;
+
// Set up the data source before creating the ingest stream
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId);
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
@@ -238,51 +284,48 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
ingestStream = IngestManager.getInstance().openIngestStream(image, settings);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error starting ingest modules", ex);
- final List errors = new ArrayList<>();
- errors.add(ex.getMessage());
- callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
- return;
+ // There was an error with ingest, but the data source has already been added
+ // so proceed with the defaultIngestStream. Code in openIngestStream
+ // should have caused a dialog to popup with the errors.
+ ingestStream = new DefaultIngestStream();
}
-
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, progress, callBack);
}
-
+
/**
* Store the options from the config panel.
*/
private void readConfigSettings() {
- if (!setDataSourceOptionsCalled) {
- configPanel.storeSettings();
- deviceId = UUID.randomUUID().toString();
- imagePath = configPanel.getContentPaths();
- sectorSize = configPanel.getSectorSize();
- timeZone = configPanel.getTimeZone();
- ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
- md5 = configPanel.getMd5();
- if (md5.isEmpty()) {
- md5 = null;
- }
- sha1 = configPanel.getSha1();
- if (sha1.isEmpty()) {
- sha1 = null;
- }
- sha256 = configPanel.getSha256();
- if (sha256.isEmpty()) {
- sha256 = null;
- }
+ configPanel.storeSettings();
+ deviceId = UUID.randomUUID().toString();
+ imagePath = configPanel.getContentPaths();
+ sectorSize = configPanel.getSectorSize();
+ timeZone = configPanel.getTimeZone();
+ ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
+ md5 = configPanel.getMd5();
+ if (md5.isEmpty()) {
+ md5 = null;
+ }
+ sha1 = configPanel.getSha1();
+ if (sha1.isEmpty()) {
+ sha1 = null;
+ }
+ sha256 = configPanel.getSha256();
+ if (sha256.isEmpty()) {
+ sha256 = null;
}
}
-
+
/**
* Check if this DSP supports ingest streams.
- *
+ *
* @return True if this DSP supports an ingest stream, false otherwise.
*/
@Override
public boolean supportsIngestStream() {
return true;
- }
+ }
/**
* Adds a data source to the case database using a background task in a
@@ -309,11 +352,11 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
ingestStream = new DefaultIngestStream();
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId);
+ new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
- errors.add(ex.getMessage());
+ errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
}
@@ -327,10 +370,10 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
* selection and configuration panel. Returns as soon as the background task
* is started and uses the callback object to signal task completion and
* return results.
- *
- * The image should be loaded in the database and stored in "image"
- * before calling this method. Additionally, an ingest stream should be initialized
- * and stored in "ingestStream".
+ *
+ * The image should be loaded in the database and stored in "image" before
+ * calling this method. Additionally, an ingest stream should be initialized
+ * and stored in "ingestStream".
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is
@@ -352,28 +395,28 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
*/
private void doAddImageProcess(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
- // If the data source or ingest stream haven't been initialized, stop processing
- if (ingestStream == null) {
- String message = "Ingest stream was not initialized before running the add image process on " + imagePath;
- logger.log(Level.SEVERE, message);
- final List errors = new ArrayList<>();
- errors.add(message);
- callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
- return;
- }
- if (image == null) {
- String message = "Image was not added to database before running the add image process on " + imagePath;
- logger.log(Level.SEVERE, message);
- final List errors = new ArrayList<>();
- errors.add(message);
- callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
- return;
- }
+ // If the data source or ingest stream haven't been initialized, stop processing
+ if (ingestStream == null) {
+ String message = "Ingest stream was not initialized before running the add image process on " + imagePath;
+ logger.log(Level.SEVERE, message);
+ final List errors = new ArrayList<>();
+ errors.add(message);
+ callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
+ return;
+ }
+ if (image == null) {
+ String message = "Image was not added to database before running the add image process on " + imagePath;
+ logger.log(Level.SEVERE, message);
+ final List errors = new ArrayList<>();
+ errors.add(message);
+ callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
+ return;
+ }
- AddImageTask.ImageDetails imageDetails = new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, null);
- addImageTask = new AddImageTask(imageDetails,
- progressMonitor,
- new StreamingAddDataSourceCallbacks(ingestStream),
+ AddImageTask.ImageDetails imageDetails = new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, null);
+ addImageTask = new AddImageTask(imageDetails,
+ progressMonitor,
+ new StreamingAddDataSourceCallbacks(ingestStream),
new StreamingAddImageTaskCallback(ingestStream, callback));
new Thread(addImageTask).start();
}
@@ -405,8 +448,8 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
imagePath = null;
timeZone = null;
ignoreFatOrphanFiles = false;
+ host = null;
configPanel.reset();
- setDataSourceOptionsCalled = false;
}
private static boolean isAcceptedByFiler(File file, List filters) {
@@ -428,7 +471,6 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
try {
// verify that the image has a file system that TSK can process
- Case currentCase = Case.getCurrentCaseThrows();
if (!DataSourceUtils.imageHasFileSystem(dataSourcePath)) {
// image does not have a file system that TSK can process
return 0;
@@ -443,41 +485,53 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
@Override
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
+ process(deviceId, dataSourcePath, null, progressMonitor, callBack);
+ }
+
+ @Override
+ public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
+ // this method does not use the config panel
this.deviceId = deviceId;
this.imagePath = dataSourcePath.toString();
this.sectorSize = 0;
this.timeZone = Calendar.getInstance().getTimeZone().getID();
+ this.host = host;
this.ignoreFatOrphanFiles = false;
- setDataSourceOptionsCalled = true;
-
+
ingestStream = new DefaultIngestStream();
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId);
+ new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
- errors.add(ex.getMessage());
+ errors.add(ex.getMessage());
callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
}
-
+
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
}
-
+
@Override
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
+ return processWithIngestStream(deviceId, dataSourcePath, null, settings, progressMonitor, callBack);
+ }
+
+ @Override
+ public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
+ // this method does not use the config panel
this.deviceId = deviceId;
this.imagePath = dataSourcePath.toString();
this.sectorSize = 0;
this.timeZone = Calendar.getInstance().getTimeZone().getID();
+ this.host = host;
this.ignoreFatOrphanFiles = false;
- setDataSourceOptionsCalled = true;
-
+
// Set up the data source before creating the ingest stream
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId);
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
@@ -495,33 +549,10 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
errors.add(ex.getMessage());
callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return null;
- }
-
+ }
+
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
+
return ingestStream;
}
-
- /**
- * Sets the configuration of the data source processor without using the
- * selection and configuration panel.
- *
- * @param imagePath Path to the image file.
- * @param timeZone The time zone to use when processing dates
- * and times for the image, obtained from
- * java.util.TimeZone.getID.
- * @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
- * FAT filesystem.
- *
- * @deprecated Use the provided overload of the run method instead.
- */
- @Deprecated
- public void setDataSourceOptions(String imagePath, String timeZone, boolean ignoreFatOrphanFiles) {
- this.deviceId = UUID.randomUUID().toString();
- this.imagePath = imagePath;
- this.sectorSize = 0;
- this.timeZone = Calendar.getInstance().getTimeZone().getID();
- this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
- setDataSourceOptionsCalled = true;
- }
-
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
index 76f328a825..eda7149f66 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2018 Basis Technology Corp.
+ * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,6 +35,7 @@ import org.sleuthkit.autopsy.coreutils.DriveUtils;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PathValidator;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
+import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
import org.sleuthkit.datamodel.HashUtility;
/**
@@ -48,8 +49,10 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
private static final long serialVersionUID = 1L;
private static final String PROP_LASTIMAGE_PATH = "LBL_LastImage_PATH"; //NON-NLS
private static final String[] SECTOR_SIZE_CHOICES = {"Auto Detect", "512", "1024", "2048", "4096"};
- private final JFileChooser fileChooser = new JFileChooser();
+ private final JFileChooserFactory fileChooserHelper = new JFileChooserFactory();
+ private JFileChooser fileChooser;
private final String contextName;
+ private final List fileChooserFilters;
/**
* Creates new form ImageFilePanel
@@ -73,14 +76,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
sectorSizeComboBox.setSelectedIndex(0);
errorLabel.setVisible(false);
-
- fileChooser.setDragEnabled(false);
- fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
- fileChooser.setMultiSelectionEnabled(false);
- fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
- if (fileChooserFilters.isEmpty() == false) {
- fileChooser.setFileFilter(fileChooserFilters.get(0));
- }
+ this.fileChooserFilters = fileChooserFilters;
}
/**
@@ -132,6 +128,21 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
private JTextField getSha256TextField() {
return sha256HashTextField;
}
+
+ private JFileChooser getChooser() {
+ if(fileChooser == null) {
+ fileChooser = fileChooserHelper.getChooser();
+ fileChooser.setDragEnabled(false);
+ fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fileChooser.setMultiSelectionEnabled(false);
+ fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
+ if (fileChooserFilters.isEmpty() == false) {
+ fileChooser.setFileFilter(fileChooserFilters.get(0));
+ }
+ }
+
+ return fileChooser;
+ }
/**
* This method is called from within the constructor to initialize the form.
@@ -298,12 +309,13 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
String oldText = getContentPaths();
// set the current directory of the FileChooser if the ImagePath Field is valid
File currentDir = new File(oldText);
+ JFileChooser chooser = getChooser();
if (currentDir.exists()) {
- fileChooser.setCurrentDirectory(currentDir);
+ chooser.setCurrentDirectory(currentDir);
}
- if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
- String path = fileChooser.getSelectedFile().getPath();
+ if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = chooser.getSelectedFile().getPath();
if (path.endsWith(".001")) {
String zeroX3_path = StringUtils.removeEnd(path, ".001") + ".000";
if (new File(zeroX3_path).exists()) {
@@ -469,7 +481,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
return false;
}
- if (!PathValidator.isValidForMultiUserCase(path, Case.getCurrentCase().getCaseType())) {
+ if (!PathValidator.isValidForCaseType(path, Case.getCurrentCase().getCaseType())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
index c183e0de36..4ec9df679e 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
@@ -1,11 +1,6 @@