merge from develop

This commit is contained in:
Greg DiCristofaro 2022-11-07 20:31:02 -05:00
commit 681d208ee1
4476 changed files with 160567 additions and 92790 deletions

6
.gitattributes vendored
View File

@ -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

10
.gitignore vendored
View File

@ -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

View File

@ -10,6 +10,16 @@
<property name="thirdparty.dir" value="${basedir}/../thirdparty" />
<!-- import ant-contrib tools -->
<property name="ant-contrib.dir" value="${thirdparty.dir}/ant-contrib/1.0b3" />
<property name="ant.contrib.jar" value="${ant-contrib.dir}/ant-contrib.jar" />
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${ant.contrib.jar}"/>
</classpath>
</taskdef>
<property name="modules.dir" value="${basedir}/release/modules/" />
<property name="ext.dir" value="${modules.dir}/ext" />
<property name="test-input" location="test/qa-functional/data"/>
@ -21,6 +31,17 @@
</target>
<target name="get-thirdparty-dependencies" description="get third-party dependencies">
<!--
Copy netbeans localization jars:
This contains jars provided in Netbeans 8 RCP that provide localization bundles.
They do not appear to be included in Netbeans >= 9.
See VIK-7434 for more information.
-->
<mkdir dir="${modules.dir}/locale"/>
<copy todir="${modules.dir}/locale" >
<fileset dir="${thirdparty.dir}/NetbeansLocalization"/>
</copy>
<!--Copy photorec to release-->
<copy todir="${basedir}/release/photorec_exec" >
<fileset dir="${thirdparty.dir}/photorec_exec"/>
@ -73,32 +94,19 @@
<copy todir="${basedir}/release/OfficialHashSets" >
<fileset dir="${thirdparty.dir}/OfficialHashSets"/>
</copy>
<!--Copy ImageMagick to release-->
<copy todir="${basedir}/release/ImageMagick-7.0.10-27-portable-Q16-x64" >
<fileset dir="${thirdparty.dir}/ImageMagick-7.0.10-27-portable-Q16-x64"/>
<!--Copy DomainCategorization to release-->
<copy todir="${basedir}/release/DomainCategorization" >
<fileset dir="${thirdparty.dir}/DomainCategorization"/>
</copy>
<!-- The 'libgstlibav.dll' file is too big to store on GitHub, so we
have it stored in a ZIP file. We'll extract it in place and remove
the ZIP file afterward. -->
<property name="gstreamer-base-path" value="${basedir}/release/gstreamer/1.0/" />
<unzip src="${gstreamer-base-path}/x86_64/lib/gstreamer-1.0/libgstlibav.zip"
dest="${gstreamer-base-path}/x86_64/lib/gstreamer-1.0/"/>
<delete file="${gstreamer-base-path}/x86_64/lib/gstreamer-1.0/libgstlibav.zip" />
<unzip src="${gstreamer-base-path}/x86/lib/gstreamer-1.0/libgstlibav.zip"
dest="${gstreamer-base-path}/x86/lib/gstreamer-1.0/"/>
<delete file="${gstreamer-base-path}/x86/lib/gstreamer-1.0/libgstlibav.zip" />
<!--Copy other jars-->
<copy file="${thirdparty.dir}/rejistry/Rejistry-1.1-SNAPSHOT.jar" todir="${ext.dir}" />
<copy file="${thirdparty.dir}/sevenzip/sevenzipjbinding.jar" todir="${ext.dir}" />
<copy file="${thirdparty.dir}/sevenzip/sevenzipjbinding-AllPlatforms.jar" todir="${ext.dir}" />
<copy file="${thirdparty.dir}/stix/StixLib.jar" todir="${ext.dir}" />
<!-- <copy file="${thirdparty.dir}/stix/StixLib.jar" todir="${ext.dir}" /> -->
<copy todir="${ext.dir}">
<fileset dir="${thirdparty.dir}/IcePDF 6.2.2/"/>
<fileset dir="${thirdparty.dir}/jai/"/>
</copy>
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5.jar" todir="${ext.dir}" />
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5-contrib.jar" todir="${ext.dir}" />
@ -126,16 +134,16 @@
<property environment="env"/>
<copy file="${env.TSK_HOME}/bindings/java/dist/sleuthkit-${TSK_VERSION}.jar"
tofile="${ext.dir}/sleuthkit-${TSK_VERSION}.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.25.2.jar"
tofile="${ext.dir}/sqlite-jdbc-3.25.2.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/postgresql-42.2.18.jar"
tofile="${ext.dir}/postgresql-42.2.18.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/mchange-commons-java-0.2.9.jar"
tofile="${ext.dir}/mchange-commons-java-0.2.9.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/c3p0-0.9.5.jar"
tofile="${ext.dir}/c3p0-0.9.5.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.36.0.3.jar"
tofile="${ext.dir}/sqlite-jdbc-3.36.0.3.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/postgresql-42.3.5.jar"
tofile="${ext.dir}/postgresql-42.3.5.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/c3p0-0.9.5.5.jar"
tofile="${ext.dir}/c3p0-0.9.5.5.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/mchange-commons-java-0.2.20.jar"
tofile="${ext.dir}/mchange-commons-java-0.2.20.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/SparseBitSet-1.1.jar"
tofile="${ext.dir}/SparseBitSet-1.1.jar"/>
tofile="${ext.dir}/SparseBitSet-1.1.jar"/>
<copy file="${env.TSK_HOME}/case-uco/java/dist/sleuthkit-caseuco-${TSK_VERSION}.jar"
tofile="${ext.dir}/sleuthkit-caseuco-${TSK_VERSION}.jar"/>
</target>
@ -149,12 +157,11 @@
<target name="getTestDataFiles">
<mkdir dir="${basedir}/test/qa-functional/data"/>
<get src="https://drive.google.com/uc?id=1gyKzqJHtaBjFBqeB29N5vSpf1oH9N0bV" dest="${test-input}/EmbeddedIM_img1_v2.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1gyKzqJHtaBjFBqeB29N5vSpf1oH9N0bV" dest="${test-input}/EmbeddedIM_img1_v2.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1gvvV797dKczkwpWII4hIryBXCc0w5zL-" dest="${test-input}/BitlockerDetection_img1_v1.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1lYzd--9YUB7yDccM7NPOo8PC1xxuOiKs" dest="${test-input}/SqlCipherDetection_img1_v1.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1QRNKs824kksiJLZ4qcs59Nytw0fJKEjb" dest="${test-input}/IngestFilters_img1_v1.img" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1OMTB5gD4_VuaFkLWu2I33FN8VAHoRQbW" dest="${test-input}/IngestFilters_local1_v1.zip" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1WGMkivlDi_I_vB1aYY6puAPktbmlNSL-" dest="${test-input}/PasswordDetection_img1_v1.img" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1X2DzJOJ1SjUkAtZXJ3oQHXkjF0NX_jOz" dest="${test-input}/VeracryptDetection_img1_v1.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=19gRepVVvLsDHtBwIkX2VVjsBWIub7aIV" dest="${test-input}/CommonFiles_img1_v1.vhd" skipexisting="true"/>
<get src="https://drive.google.com/uc?id=1chUMtA0CNyPBZ0yuTl9F_O103R21Ox0p" dest="${test-input}/CommonFiles_img2_v1.vhd" skipexisting="true"/>
@ -178,11 +185,16 @@
<copy file="${thirdparty.dir}/LICENSE-2.0.txt" todir="${ext.dir}" />
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
<ivy:resolve log="quiet"/>
<!-- Make a report that lists out the dependencies that our JARs have -->
<ivy:report todir='${basedir}/build/ivy-reports' graph='true' xml='false'/>
<ivy:retrieve conf="core" pattern="${ext.dir}/[artifact]-[revision](-[classifier]).[ext]" />
</target>
<target name="init" depends="get-deps,harness.init"/>
<target name="clean" depends="projectized-common.clean">
<!--Override clean to delete jars, etc downloaded with Ivy,
or copied in from thirdparty folder. This way we don't end up with
@ -193,7 +205,7 @@
<target name="compile" depends="projectized-common.compile">
<antcall target="copy-bundle" />
</target>
<target name="copy-bundle">
<!-- the externalized strings in 'src' are in both the java files as annotations and in the Bundle.property files.
The strings get merged during compilation. This target copies that merged file into src so that it can be checked
@ -206,9 +218,40 @@
</copy>
</target>
<!--sets up integration test system properties, calls underlying test-init and then sets up the pathing jar-->
<target name="test-init" depends="projectized-common.test-init,getTestDataFiles,qa-functional-pathing-jar,unit-test-path-simplification" />
<!--sets up integration test system properties, calls underlying test-init,
get test data files if they have not been retrieved, and then sets up the pathing jar and unit test simplification -->
<target name="test-init" depends="setup-integration-props,projectized-common.test-init,getTestDataFiles,qa-functional-pathing-jar,unit-test-path-simplification" />
<target name="test-qa-functional">
<!--We don't want integration testing to run from standard qa functional-->
<property name="test.excludes" value="**/org/sleuthkit/autopsy/integrationtesting/TestRunner.class"/>
<antcall target="projectized-common.test-qa-functional" />
</target>
<!--map from integration-test variables to test-qa-functional-sys-prop so they will be used as system properties-->
<target name="setup-integration-props" depends="init">
<propertyselector
property="integration-test-sys-props"
match="^integration-test\.(.*)"
select="\1"
delimiter=","
casesensitive="true"
distinct="true"
/>
<for list="${integration-test-sys-props}" param="integration-test-sys-prop">
<sequential>
<property
name="test-qa-functional-sys-prop.integration-test.@{integration-test-sys-prop}"
value="${integration-test.@{integration-test-sys-prop}}"
/>
</sequential>
</for>
</target>
<!--
The paths specified in 'module.run.classpath' are incorporated into the manifest of a jar and then the path to the
jar is used as part of the classpath for '-do-junit' instead of 'module.run.classpath'. This was done to prevent
@ -247,6 +290,18 @@
<pathelement path="${test.extra.nb.javac.deps}"/>
</path>
</sequential>
</target>
<target name="integration-test">
<!--We want only integration testing to run from this-->
<sequential>
<property name="test.includes" value="**/org/sleuthkit/autopsy/integrationtesting/TestRunner.class"/>
<!-- This overrides the value in common.xml:test-init that sets each test lasting 10 minutes maximum.
More information on the timeout can be found here: http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-nbjunit/org/netbeans/junit/NbTestCase.html
under timeout() or in the harness README. Current value is 4 hours (4 * 60 * 60 * 1000) -->
<property name="test.timeout" value="14400000"/>
<antcall target="projectized-common.test-qa-functional" />
</sequential>
</target>

View File

@ -3,58 +3,86 @@
<configurations >
<!-- module dependencies -->
<conf name="core"/>
</configurations>
<dependencies >
<dependency conf="core->default" org="com.github.vlsi.mxgraph" name="jgraphx" rev="4.1.0" />
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.16.0"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="2.8.0"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="2.8.0"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-recipes" rev="2.8.0"/>
<dependency conf="core->default" org="com.github.vlsi.mxgraph" name="jgraphx" rev="4.2.2" />
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.16.4"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="5.2.1"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="5.2.1"/>
<dependency conf="core->default" org="org.apache.curator" name="curator-recipes" rev="5.2.1"/>
<dependency conf="core->default" org="org.python" name="jython-standalone" rev="2.7.2" />
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess" rev="2.2.0"/>
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess-encrypt" rev="2.1.4"/>
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
<dependency conf="core->default" org="commons-codec" name="commons-codec" rev="1.11"/>
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="6.1.11"/>
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.8.0"/>
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
<dependency conf="core->default" org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.9.7"/>
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.11.0"/>
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess" rev="4.0.1"/>
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess-encrypt" rev="4.0.1"/>
<dependency conf="core->default" org="com.google.cloud" name="google-cloud-translate" rev="1.70.0"/>
<dependency conf="core->default" org="org.apache.opennlp" name="opennlp-tools" rev="1.9.1"/>
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.9.0"/>
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.14.3"/>
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.17.0"/>
<dependency conf="core->default" org="com.ethteck.decodetect" name="decodetect-core" rev="0.3"/>
<dependency conf="core->default" org="org.sejda.webp-imageio" name="webp-imageio-sejda" rev="0.1.0"/>
<dependency conf="core->default" org="com.googlecode.libphonenumber" name="libphonenumber" rev="3.5" />
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
<dependency conf="core->default" org="com.googlecode.libphonenumber" name="libphonenumber" rev="8.12.45" />
<dependency conf="core->default" org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
<dependency conf="core->default" org="org.jfree" name="jfreechart" rev="1.0.19"/>
<dependency conf="core->default" org="org.jfree" name="jfreechart" rev="1.5.3"/>
<!-- for yaml reading/writing -->
<dependency conf="core->default" org="org.yaml" name="snakeyaml" rev="1.30"/>
<!-- map support for geolocation -->
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
<!-- For Discovery testing -->
<dependency conf="core->default" org="org.mockito" name="mockito-core" rev="3.5.7"/>
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.6"/>
<!-- for handling diffs -->
<dependency conf="core->default" org="io.github.java-diff-utils" name="java-diff-utils" rev="4.11"/>
<!-- JAXB -->
<dependency conf="core->default" org="javax.xml.bind" name="jaxb-api" rev="2.3.1"/>
<dependency conf="core->default" org="org.glassfish.jaxb" name="jaxb-runtime" rev="2.3.3"/>
<dependency conf="core->default" org="org.icepdf.os" name="icepdf-viewer" rev="6.2.2">
<!-- get the new latest batik items below, override bouncy castle -->
<exclude org="batik" module="batik-awt-util"/>
<exclude org="batik" module="batik-dom"/>
<exclude org="batik" module="batik-svg-dom"/>
<exclude org="batik" module="batik-svggen"/>
<exclude org="batik" module="batik-util"/>
<exclude org="batik" module="batik-xml"/>
<exclude org="batik" module="batik-xml"/>
<!-- doesn't work with ivy; will be added separately -->
<exclude org="javax.media" module="jai_core"/>
<exclude org="com.sun.media" module="jai_imageio"/>
</dependency>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-awt-util" rev="1.14"/>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-dom" rev="1.14"/>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-svg-dom" rev="1.14"/>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-svggen" rev="1.14"/>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-util" rev="1.14"/>
<dependency conf="core->default" org="org.apache.xmlgraphics" name="batik-xml" rev="1.14"/>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency conf="core->default" org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
<dependency conf="core->default" org="javax.ws.rs" name="javax.ws.rs-api" rev="2.1.1"/>
<!-- annotations like guarded by -->
<dependency conf="core->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.6.0"/>
<override org="org.apache.zookeeper" module="zookeeper" rev="3.8.0"/>
<override org="org.apache.zookeeper" module="zookeeper-jute" rev="3.8.0"/>
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
<override org="org.slf4j" module="slf4j-api" rev="1.7.36"/>
<override org="com.google.guava" module="guava" rev="31.1-jre"/>
<override org="com.fasterxml.jackson.core" module="jackson-core" rev="2.13.2"/>
<!-- changes to bouncy castle version may also be reflected in thirdparty/IcePDF 6.2.2 -->
<override org="org.bouncycastle" module="bcprov-ext-jdk15on" rev="1.70"/>
<override org="org.bouncycastle" module="bcprov-jdk15on" rev="1.70"/>
<override org="org.bouncycastle" module="bcpkix-jdk15on" rev="1.70"/>
</dependencies>
</ivy-module>

View File

@ -6,4 +6,5 @@
<ibiblio name="maven.restlet.org" root="http://maven.restlet.com" m2compatible="true" />
</chain>
</resolvers>
<property name="packaging.type" value="jar" />
</ivysettings>

View File

@ -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

View File

@ -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

View File

@ -269,6 +269,11 @@
<code-name-base>org.netbeans.modules.nbjunit</code-name-base>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.sleuthkit.autopsy.coretestlibs</code-name-base>
<recursive/>
<compile-dependency/>
</test-dependency>
</test-type>
<test-type>
<name>qa-functional</name>
@ -293,6 +298,10 @@
<recursive/>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.sleuthkit.autopsy.coretestlibs</code-name-base>
<compile-dependency/>
</test-dependency>
</test-type>
</test-dependencies>
<public-packages>
@ -336,509 +345,365 @@
<package>org.sleuthkit.autopsy.textextractors.configs</package>
<package>org.sleuthkit.autopsy.textsummarizer</package>
<package>org.sleuthkit.autopsy.texttranslation</package>
<package>org.sleuthkit.autopsy.url.analytics</package>
<package>org.sleuthkit.datamodel</package>
<package>org.sleuthkit.datamodel.blackboardutils</package>
<package>org.sleuthkit.datamodel.blackboardutils.attributes</package>
</public-packages>
<class-path-extension>
<runtime-relative-path>ext/batik-xml-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-xml-1.6.jar</binary-origin>
<runtime-relative-path>ext/activemq-all-5.16.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/activemq-all-5.16.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-digester-1.8.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-digester-1.8.1.jar</binary-origin>
<runtime-relative-path>ext/audience-annotations-0.12.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/audience-annotations-0.12.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jai_core-1.1.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jai_core-1.1.3.jar</binary-origin>
<runtime-relative-path>ext/batik-awt-util-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-awt-util-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gax-grpc-1.44.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\gax-grpc-1.44.0.jar</binary-origin>
<runtime-relative-path>ext/batik-dom-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-dom-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/failureaccess-1.0.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\failureaccess-1.0.1.jar</binary-origin>
<runtime-relative-path>ext/batik-svg-dom-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-svg-dom-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-protobuf-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-protobuf-1.19.0.jar</binary-origin>
<runtime-relative-path>ext/batik-svggen-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-svggen-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opencensus-api-0.19.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\opencensus-api-0.19.2.jar</binary-origin>
<runtime-relative-path>ext/batik-util-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-util-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/batik-svg-dom-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-svg-dom-1.6.jar</binary-origin>
<runtime-relative-path>ext/batik-xml-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/batik-xml-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gax-httpjson-0.61.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\gax-httpjson-0.61.0.jar</binary-origin>
<runtime-relative-path>ext/bcpkix-jdk15on-1.70.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcpkix-jdk15on-1.70.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
<binary-origin>release\modules\ext\sevenzipjbinding.jar</binary-origin>
<runtime-relative-path>ext/bcprov-ext-jdk15on-1.70.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcprov-ext-jdk15on-1.70.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
<binary-origin>release\modules\ext\mchange-commons-java-0.2.9.jar</binary-origin>
<runtime-relative-path>ext/bcprov-jdk15on-1.70.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcprov-jdk15on-1.70.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/api-common-1.7.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\api-common-1.7.0.jar</binary-origin>
<runtime-relative-path>ext/c3p0-0.9.5.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/c3p0-0.9.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackson-databind-2.9.7.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jackson-databind-2.9.7.jar</binary-origin>
<runtime-relative-path>ext/checker-qual-3.12.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/checker-qual-3.12.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/okhttp-2.7.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\okhttp-2.7.5.jar</binary-origin>
<runtime-relative-path>ext/commons-dbcp2-2.9.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-dbcp2-2.9.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/proto-google-cloud-translate-v3beta1-0.53.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\proto-google-cloud-translate-v3beta1-0.53.0.jar</binary-origin>
<runtime-relative-path>ext/commons-io-2.11.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-io-2.11.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/byte-buddy-1.10.13.jar</runtime-relative-path>
<binary-origin>release\modules\ext\byte-buddy-1.10.13.jar</binary-origin>
<runtime-relative-path>ext/commons-lang3-3.10.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang3-3.10.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/error_prone_annotations-2.3.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\error_prone_annotations-2.3.2.jar</binary-origin>
<runtime-relative-path>ext/commons-logging-1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/libphonenumber-3.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\libphonenumber-3.5.jar</binary-origin>
<runtime-relative-path>ext/commons-pool2-2.10.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-pool2-2.10.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/StixLib.jar</runtime-relative-path>
<binary-origin>release\modules\ext\StixLib.jar</binary-origin>
<runtime-relative-path>ext/curator-client-5.2.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/curator-client-5.2.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-auth-library-credentials-0.15.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-auth-library-credentials-0.15.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-auth-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-auth-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/j2objc-annotations-1.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\j2objc-annotations-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.11.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\metadata-extractor-2.11.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-codec-1.11.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-codec-1.11.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/postgresql-42.2.18.jar</runtime-relative-path>
<binary-origin>release\modules\ext\postgresql-42.2.18.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-pool2-2.4.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-pool2-2.4.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jxmapviewer2-2.4.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jxmapviewer2-2.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jdom-2.0.5-contrib.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jdom-2.0.5-contrib.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\xmpcore-5.1.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/batik-util-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-util-1.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javax.annotation-api-1.3.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\javax.annotation-api-1.3.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jgraphx-4.1.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jgraphx-4.1.0.jar</binary-origin>
<runtime-relative-path>ext/curator-framework-5.2.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/curator-framework-5.2.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/jython-standalone-2.7.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jython-standalone-2.7.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jline-0.9.94.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jline-0.9.94.jar</binary-origin>
=======
<runtime-relative-path>ext/curator-recipes-5.2.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/curator-recipes-5.2.1.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/DatCon.jar</runtime-relative-path>
<binary-origin>release\modules\ext\DatCon.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/okio-1.6.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\okio-1.6.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcprov-jdk15on-1.54.jar</runtime-relative-path>
<binary-origin>release\modules\ext\bcprov-jdk15on-1.54.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\curator-framework-2.8.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-dbcp2-2.1.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-dbcp2-2.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-http-client-appengine-1.29.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-http-client-appengine-1.29.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/proto-google-iam-v1-0.12.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\proto-google-iam-v1-0.12.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-encrypt-2.1.4.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jackcess-encrypt-2.1.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-http-client-1.29.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-http-client-1.29.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opennlp-tools-1.9.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\opennlp-tools-1.9.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcprov-ext-jdk15on-1.54.jar</runtime-relative-path>
<binary-origin>release\modules\ext\bcprov-ext-jdk15on-1.54.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-cloud-core-1.70.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-cloud-core-1.70.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/protobuf-java-3.7.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\protobuf-java-3.7.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcpkix-jdk15on-1.54.jar</runtime-relative-path>
<binary-origin>release\modules\ext\bcpkix-jdk15on-1.54.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sqlite-jdbc-3.25.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\sqlite-jdbc-3.25.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-protobuf-lite-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-protobuf-lite-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpcore-4.4.9.jar</runtime-relative-path>
<binary-origin>release\modules\ext\httpcore-4.4.9.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/guava-27.1-android.jar</runtime-relative-path>
<binary-origin>release\modules\ext\guava-27.1-android.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcprov-jdk15on-1.52.jar</runtime-relative-path>
<binary-origin>release\modules\ext\bcprov-jdk15on-1.52.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/checker-compat-qual-2.5.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\checker-compat-qual-2.5.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/animal-sniffer-annotations-1.17.jar</runtime-relative-path>
<binary-origin>release\modules\ext\animal-sniffer-annotations-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gax-1.44.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\gax-1.44.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jsoup-1.10.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jsoup-1.10.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/YaraJNIWrapper.jar</runtime-relative-path>
<binary-origin>release/modules/ext/YaraJNIWrapper.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-context-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-context-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-2.2.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jackcess-2.2.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/slf4j-log4j12-1.7.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\slf4j-log4j12-1.7.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jericho-html-3.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jericho-html-3.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-cloud-core-grpc-1.70.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-cloud-core-grpc-1.70.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-validator-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-validator-1.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/slf4j-api-1.7.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\slf4j-api-1.7.6.jar</binary-origin>
<binary-origin>release/modules/ext/DatCon.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/decodetect-core-0.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\decodetect-core-0.3.jar</binary-origin>
<binary-origin>release/modules/ext/decodetect-core-0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/mockito-core-3.5.7.jar</runtime-relative-path>
<binary-origin>release\modules\ext\mockito-core-3.5.7.jar</binary-origin>
<runtime-relative-path>ext/error_prone_annotations-2.11.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/error_prone_annotations-2.11.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpclient-4.5.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\httpclient-4.5.5.jar</binary-origin>
<runtime-relative-path>ext/failureaccess-1.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/failureaccess-1.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/curator-recipes-2.8.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\curator-recipes-2.8.0.jar</binary-origin>
<runtime-relative-path>ext/guava-31.1-jre.jar</runtime-relative-path>
<binary-origin>release/modules/ext/guava-31.1-jre.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackson-annotations-2.9.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jackson-annotations-2.9.0.jar</binary-origin>
<runtime-relative-path>ext/icepdf-core-6.2.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/icepdf-core-6.2.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/objenesis-3.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\objenesis-3.1.jar</binary-origin>
<runtime-relative-path>ext/icepdf-viewer-6.2.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/icepdf-viewer-6.2.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackson-core-2.9.7.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jackson-core-2.9.7.jar</binary-origin>
<runtime-relative-path>ext/j2objc-annotations-1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/j2objc-annotations-1.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang3-3.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-lang3-3.5.jar</binary-origin>
<runtime-relative-path>ext/jackcess-4.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-4.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/log4j-1.2.16.jar</runtime-relative-path>
<binary-origin>release\modules\ext\log4j-1.2.16.jar</binary-origin>
<runtime-relative-path>ext/jackcess-encrypt-4.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-encrypt-4.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-logging-1.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-logging-1.2.jar</binary-origin>
<runtime-relative-path>ext/jai_core-1.1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jai_core-1.1.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar</runtime-relative-path>
<binary-origin>release\modules\ext\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/protobuf-java-util-3.7.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\protobuf-java-util-3.7.0.jar</binary-origin>
<runtime-relative-path>ext/jai_imageio-1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jai_imageio-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/jaxb-api-2.3.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jaxb-api-2.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-collections-3.2.2.jar</binary-origin>
=======
<runtime-relative-path>ext/java-diff-utils-4.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/java-diff-utils-4.11.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\SparseBitSet-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-grpclb-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-grpclb-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/batik-svggen-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-svggen-1.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/c3p0-0.9.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\c3p0-0.9.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/zookeeper-3.4.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\zookeeper-3.4.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-alts-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-alts-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sleuthkit-caseuco-4.10.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.10.1.jar</binary-origin>
<runtime-relative-path>ext/javax.ws.rs-api-2.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javax.ws.rs-api-2.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jdom-2.0.5.jar</binary-origin>
<binary-origin>release/modules/ext/jdom-2.0.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gson-2.7.jar</runtime-relative-path>
<binary-origin>release\modules\ext\gson-2.7.jar</binary-origin>
<runtime-relative-path>ext/jfreechart-1.5.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfreechart-1.5.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-api-client-1.27.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-api-client-1.27.0.jar</binary-origin>
<runtime-relative-path>ext/jgraphx-4.2.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jgraphx-4.2.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jsoup-1.14.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jsoup-1.14.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jutf7-1.0.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jxmapviewer2-2.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jxmapviewer2-2.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jython-standalone-2.7.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jython-standalone-2.7.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/libphonenumber-8.12.45.jar</runtime-relative-path>
<binary-origin>release/modules/ext/libphonenumber-8.12.45.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/listenablefuture-1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/listenablefuture-1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/jaxb-runtime-2.3.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jaxb-runtime-2.3.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opencensus-contrib-http-util-0.19.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\opencensus-contrib-http-util-0.19.2.jar</binary-origin>
=======
<runtime-relative-path>ext/logback-classic-1.2.10.jar</runtime-relative-path>
<binary-origin>release/modules/ext/logback-classic-1.2.10.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-auth-library-oauth2-http-0.15.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-auth-library-oauth2-http-0.15.0.jar</binary-origin>
<runtime-relative-path>ext/logback-core-1.2.10.jar</runtime-relative-path>
<binary-origin>release/modules/ext/logback-core-1.2.10.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/commons-lang-2.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-lang-2.6.jar</binary-origin>
=======
<runtime-relative-path>ext/mchange-commons-java-0.2.20.jar</runtime-relative-path>
<binary-origin>release/modules/ext/mchange-commons-java-0.2.20.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jsr305-3.0.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jsr305-3.0.2.jar</binary-origin>
<runtime-relative-path>ext/metadata-extractor-2.17.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.17.0.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/proto-google-common-protos-1.15.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\proto-google-common-protos-1.15.0.jar</binary-origin>
<runtime-relative-path>ext/netty-buffer-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-buffer-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/netty-3.7.0.Final.jar</runtime-relative-path>
<binary-origin>release\modules\ext\netty-3.7.0.Final.jar</binary-origin>
<runtime-relative-path>ext/netty-codec-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-codec-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jfreechart-1.0.19.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfreechart-1.0.19.jar</binary-origin>
<runtime-relative-path>ext/netty-common-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-common-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opencensus-contrib-grpc-metrics-0.19.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\opencensus-contrib-grpc-metrics-0.19.2.jar</binary-origin>
<runtime-relative-path>ext/netty-handler-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-handler-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/netty-resolver-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-resolver-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/activemq-all-5.16.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\activemq-all-5.16.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jai_imageio-1.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jai_imageio-1.1.jar</binary-origin>
=======
<runtime-relative-path>ext/netty-tcnative-2.0.48.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-tcnative-2.0.48.Final.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/junit-3.8.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\junit-3.8.1.jar</binary-origin>
<runtime-relative-path>ext/netty-tcnative-classes-2.0.48.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-tcnative-classes-2.0.48.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/istack-commons-runtime-3.0.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/istack-commons-runtime-3.0.11.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/curator-client-2.8.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\curator-client-2.8.0.jar</binary-origin>
=======
<runtime-relative-path>ext/netty-transport-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-transport-4.1.73.Final.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-core-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-core-1.19.0.jar</binary-origin>
<runtime-relative-path>ext/netty-transport-classes-epoll-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-transport-classes-epoll-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javax.ws.rs-api-2.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\javax.ws.rs-api-2.0.jar</binary-origin>
<runtime-relative-path>ext/netty-transport-native-epoll-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-transport-native-epoll-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jcommon-1.0.23.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jcommon-1.0.23.jar</binary-origin>
<runtime-relative-path>ext/netty-transport-native-unix-common-4.1.73.Final.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netty-transport-native-unix-common-4.1.73.Final.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/icepdf-core-6.2.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\icepdf-core-6.2.2.jar</binary-origin>
<runtime-relative-path>ext/okhttp-2.7.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/okhttp-2.7.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<<<<<<< HEAD
<runtime-relative-path>ext/google-cloud-core-http-1.70.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-cloud-core-http-1.70.0.jar</binary-origin>
=======
<runtime-relative-path>ext/okio-1.6.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/okio-1.6.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/postgresql-42.3.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/postgresql-42.3.5.jar</binary-origin>
>>>>>>> c8f546a0d7078b675a4eb673ba25e4acd1523985
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/Rejistry-1.1-SNAPSHOT.jar</runtime-relative-path>
<binary-origin>release\modules\ext\Rejistry-1.1-SNAPSHOT.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-beanutils-1.9.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-beanutils-1.9.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/batik-dom-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-dom-1.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-http-client-jackson2-1.29.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-http-client-jackson2-1.29.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/threetenbp-1.3.3.jar</runtime-relative-path>
<binary-origin>release\modules\ext\threetenbp-1.3.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-cloud-translate-1.70.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-cloud-translate-1.70.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-stub-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-stub-1.19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-oauth-client-1.28.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-oauth-client-1.28.0.jar</binary-origin>
<binary-origin>release/modules/ext/Rejistry-1.1-SNAPSHOT.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
<binary-origin>release\modules\ext\sevenzipjbinding-AllPlatforms.jar</binary-origin>
<binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sleuthkit-4.10.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sleuthkit-4.10.1.jar</binary-origin>
<runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\jutf7-1.0.0.jar</binary-origin>
<runtime-relative-path>ext/sleuthkit-4.11.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sleuthkit-4.11.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/byte-buddy-agent-1.10.13.jar</runtime-relative-path>
<binary-origin>release\modules\ext\byte-buddy-agent-1.10.13.jar</binary-origin>
<runtime-relative-path>ext/sleuthkit-caseuco-4.11.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.11.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/batik-awt-util-1.6.jar</runtime-relative-path>
<binary-origin>release\modules\ext\batik-awt-util-1.6.jar</binary-origin>
<runtime-relative-path>ext/snakeyaml-1.30.jar</runtime-relative-path>
<binary-origin>release/modules/ext/snakeyaml-1.30.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\google-api-services-translate-v2-rev20170525-1.27.0.jar</binary-origin>
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/SparseBitSet-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/icepdf-viewer-6.2.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\icepdf-viewer-6.2.2.jar</binary-origin>
<runtime-relative-path>ext/spotbugs-annotations-4.6.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spotbugs-annotations-4.6.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/webp-imageio-sejda-0.1.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\webp-imageio-sejda-0.1.0.jar</binary-origin>
<runtime-relative-path>ext/sqlite-jdbc-3.36.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sqlite-jdbc-3.36.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/grpc-netty-shaded-1.19.0.jar</runtime-relative-path>
<binary-origin>release\modules\ext\grpc-netty-shaded-1.19.0.jar</binary-origin>
<runtime-relative-path>ext/xmpcore-6.1.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-6.1.11.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/YaraJNIWrapper.jar</runtime-relative-path>
<binary-origin>release/modules/ext/YaraJNIWrapper.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/zookeeper-3.8.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/zookeeper-3.8.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/zookeeper-jute-3.8.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/zookeeper-jute-3.8.0.jar</binary-origin>
</class-path-extension>
</data>
</configuration>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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();
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2020 Basis Technology Corp.
* Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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> content = new HashSet<>();
private final Collection<Content> 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<Content> 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<String, TagName> tagNamesMap = null;
Map<String, TagName> tagNamesMap;
List<String> standardTagNames = TagsManager.getStandardTagNames();
Map<String, JMenu> tagSetMenuMap = new HashMap<>();
List<JMenuItem> standardTagMenuitems = new ArrayList<>();
@ -240,5 +252,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
return tagNameItem;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<BlackboardArtifact> selectedBlackboardArtifactsList) {

View File

@ -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 {

View File

@ -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<TagName, Void> {
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"),

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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);
}

View File

@ -0,0 +1,76 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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<Void, Void>() {
@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();
}
}

View File

@ -0,0 +1,77 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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<Void, Void>() {
@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();
}
}

View File

@ -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();

View File

@ -24,10 +24,15 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="descriptionLabel" pref="430" max="32767" attributes="0"/>
<Component id="descriptionLabel" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="casesLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="correlationValueLabel" alignment="0" min="-2" max="-2" attributes="0"/>
@ -35,16 +40,23 @@
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="correlationTypeComboBox" max="32767" attributes="0"/>
<Component id="correlationValueTextField" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="normalizedLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="correlationTypeComboBox" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="correlationValueScrollPane" min="-2" pref="379" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="142" max="-2" attributes="0"/>
</Group>
<Component id="errorLabel" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="casesLabel" max="32767" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -60,17 +72,19 @@
<Component id="correlationTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="correlationTypeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="correlationValueTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="correlationValueLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="correlationValueLabel" min="-2" max="-2" attributes="0"/>
<Component id="correlationValueScrollPane" min="-2" pref="190" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="normalizedLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="19" max="32767" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="20" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="casesLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="casesLabel" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="searchButton" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -85,16 +99,6 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="correlationValueTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/allcasessearch/Bundle.properties" key="AllCasesSearchDialog.correlationValueTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="valueFieldKeyReleaseListener"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="searchButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -158,5 +162,30 @@
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="correlationValueScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="correlationValueTextArea">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/allcasessearch/Bundle.properties" key="AllCasesSearchDialog.correlationValueTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="normalizedLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/allcasessearch/Bundle.properties" key="AllCasesSearchDialog.normalizedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -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<List<CorrelationAttributeInstance>, Void>() {
@Override
protected List<CorrelationAttributeInstance> doInBackground() {
List<CorrelationAttributeInstance> 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<String> 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<String> 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
}

View File

@ -1,10 +1,11 @@
AllCasesSearchDialog.descriptionLabel.text=<html>Search the Central Repository for correlation properties with a specified value. The search is case insensitive.</html>
AllCasesSearchDialog.descriptionLabel.text=<html>Search the Central Repository for the given values.</html>
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.

View File

@ -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=<html>Search the Central Repository for correlation properties with a specified value. The search is case insensitive.</html>
AllCasesSearchDialog.dialogTitle.text=Search All Cases
AllCasesSearchDialog.descriptionLabel.text=<html>Search the Central Repository for the given values.</html>
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

View File

@ -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=<html>\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</html>
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=<html>\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</html>
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

View File

@ -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));

View File

@ -0,0 +1,103 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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<String, Logger> 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() {
}
}

View File

@ -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?

View File

@ -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

View File

@ -0,0 +1,141 @@
/*
* Autopsy
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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
}
}

View File

@ -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) {

View File

@ -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<String> errList, List<Content> 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<String> errList, List<Content> 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);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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
}
}
}
/**

View File

@ -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
}
}

View File

@ -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<WizardDescript
private final AddImageAction action;
private int progressPanelIndex;
private int dsPanelIndex;
private int hostPanelIndex;
private int ingestPanelIndex;
private final static String PROP_LASTPROFILE_NAME = "AIW_LASTPROFILE_NAME"; //NON-NLS
private AddImageWizardSelectHostPanel hostPanel = null;
AddImageWizardIterator(AddImageAction action) {
this.action = action;
@ -55,10 +58,12 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
private List<ShortcutWizardDescriptorPanel> 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<WizardDescript
@Override
// disable the previous button on all panels except the data source panel
public boolean hasPrevious() {
return (index == dsPanelIndex); //Users should be able to back up to select a different DSP
return (index <= dsPanelIndex && index > 0); //Users should be able to back up to select a different DSP
}
/**
@ -180,8 +185,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
// so it gets going in the background while the user is still picking the Ingest modules
// This will occur when the next button is clicked on the panel where you have chosen your data to process
if (index == ingestPanelIndex) {
((AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex)).
startDataSourceProcessing(((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent().getCurrentDSProcessor());
AddImageWizardAddingProgressPanel addingProgressPanel = (AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex);
AddImageWizardDataSourceSettingsVisual dspSettingsPanel = ((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent();
Host host = (hostPanel == null) ? null : hostPanel.getSelectedHost();
addingProgressPanel.startDataSourceProcessing(dspSettingsPanel.getCurrentDSProcessor(), host);
}
boolean panelEnablesSkipping = current().panelEnablesSkipping();
boolean skipNextPanel = current().skipNextPanel();

View File

@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class AddImageWizardSelectDspPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener {
@NbBundle.Messages("SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add")
@NbBundle.Messages("SelectDataSourceProcessorPanel.name.text=Select Data Source Type")
private AddImageWizardSelectDspVisual component;
private static final String LAST_DSP_PROPERTIES_FILE = "LastDspUsed"; //NON-NLS
private static final String LAST_DSP_USED_KEY = "Last_Dsp_Used"; //NON-NLS

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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());

View File

@ -0,0 +1,96 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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();
}
}

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="radioButtonGroup">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="validationMessage" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="generateNewRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="useExistingHostRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="hostDescription" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="270" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="specifyNewHostRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="specifyNewHostTextField" min="-2" pref="270" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="13" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="hostDescription" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="generateNewRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="specifyNewHostRadio" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="specifyNewHostTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="useExistingHostRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="validationMessage" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="18" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="generateNewRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.generateNewRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="generateNewRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="specifyNewHostRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.specifyNewHostRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="specifyNewHostRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="specifyNewHostTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.specifyNewHostTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="useExistingHostRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.useExistingHostRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useExistingHostRadioActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="existingHostList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;HostListItem&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="hostDescription">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.hostDescription.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="validationMessage">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="java.awt.Color.RED" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.validationMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,374 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.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<String> 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<Host> hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getAllHosts();
sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts);
Vector<HostListItem> 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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))
);
}// </editor-fold>//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<HostListItem> 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
}

View File

@ -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<String> 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<String> localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
AddLocalFilesTask(String deviceId, String rootVirtualDirectoryName, List<String> 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());

View File

@ -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=<html>Multi-User cases are enabled but Solr 8 server has not been configured.<br>\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n</html>
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=\

View File

@ -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=<html>Multi-User cases are enabled but Solr 8 server has not been configured.<br>\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n</html>
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=\

View File

@ -1,4 +1,4 @@
#Tue Aug 18 18:09:20 UTC 2020
#Thu Sep 30 10:26:59 UTC 2021
AddImageAction.ingestConfig.ongoingIngest.msg=<html>\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<br />\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b?</html>
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=<html>\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<br>\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</html>
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\:

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012-2020 Basis Technology Corp.
* Copyright 2012-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<Long, String> imgPaths = getImagePaths(caseDb);
for (Map.Entry<Long, String> 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<Long, String> imgPaths = getImagePaths(caseDb);
for (Map.Entry<Long, String> 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.

View File

@ -218,7 +218,7 @@ public final class CaseMetadata {
*
* @return The path to the metadata file
*/
Path getFilePath() {
public Path getFilePath() {
return metadataFilePath;
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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);

View File

@ -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.
*/

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2015-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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()));
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2018 Basis Technology Corp.
* Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<FileFilter> 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<String> 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<String> 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;
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<FileFilter> 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());
}

View File

@ -1,11 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -16,6 +11,7 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
@ -35,9 +31,6 @@
<SubComponents>
<Container class="javax.swing.JPanel" name="contentPanel">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[625, 150]"/>
</Property>
@ -60,9 +53,6 @@
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[16, 16]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="null"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
@ -85,6 +75,12 @@
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="1"/>
</Property>
<Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" id="InternalFrame.borderColor" palette="3" red="f0" type="palette"/>
</Property>
<Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[4, 2]"/>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
@ -157,6 +153,12 @@
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="0"/>
</Property>
<Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" id="InternalFrame.borderColor" palette="3" red="f0" type="palette"/>
</Property>
<Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[4, 2]"/>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
</Property>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2016-2019 Basis Technology Corp.
* Copyright 2016-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -26,8 +26,12 @@ import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages;
@ -50,13 +54,14 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
private List<IngestJobInfo> ingestJobs;
private static final int EXTRA_ROW_HEIGHT = 4;
private final List<IngestJobInfo> ingestJobs = new ArrayList<>();
private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private DataSource selectedDataSource;
private static SwingWorker<Boolean, Void> refreshWorker = null;
/**
* Creates new form IngestJobInfoPanel
@ -76,23 +81,33 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
this.ingestModuleTable.setModel(this.ingestModuleTableModel);
});
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST , (PropertyChangeEvent evt) -> {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
refresh();
}
});
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
return;
}
if (CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName())) {
refresh();
// Check whether we have a case open or case close event.
if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) {
if (evt.getNewValue() != null) {
// Case open
refresh();
} else {
// Case close
reset();
}
}
});
ingestJobTable.setRowHeight(ingestJobTable.getRowHeight() + EXTRA_ROW_HEIGHT);
ingestModuleTable.setRowHeight(ingestModuleTable.getRowHeight() + EXTRA_ROW_HEIGHT);
}
/**
@ -111,32 +126,69 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
}
}
this.ingestJobTableModel = new IngestJobTableModel();
this.ingestJobTable.setModel(ingestJobTableModel);
//if there were ingest jobs select the first one by default
if (!ingestJobsForSelectedDataSource.isEmpty()) {
ingestJobTable.setRowSelectionInterval(0, 0);
}
this.repaint();
SwingUtilities.invokeLater(() -> {
this.ingestJobTable.setModel(ingestJobTableModel);
//if there were ingest jobs select the first one by default
if (!ingestJobsForSelectedDataSource.isEmpty()) {
ingestJobTable.setRowSelectionInterval(0, 0);
}
this.repaint();
});
}
/**
* Get the updated complete list of ingest jobs.
*/
private void refresh() {
try {
if (Case.isCaseOpen()) {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
this.ingestJobs = skCase.getIngestJobs();
setDataSource(selectedDataSource);
} else {
this.ingestJobs = new ArrayList<>();
setDataSource(null);
}
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
if (refreshWorker != null && !refreshWorker.isDone()) {
refreshWorker.cancel(true);
}
refreshWorker = new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
ingestJobs.clear();
try {
if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
ingestJobs.addAll(skCase.getIngestJobs());
setDataSource(selectedDataSource);
} else {
setDataSource(null);
}
return true;
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
return false;
}
}
@Override
protected void done() {
try {
if (!get()) {
JOptionPane.showMessageDialog(IngestJobInfoPanel.this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
}
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
} catch (CancellationException ignored) {
logger.log(Level.INFO, "The refreshing of the IngestJobInfoPanel was cancelled");
}
}
};
refreshWorker.execute();
}
/**
* Reset the panel.
*/
private void reset() {
if (refreshWorker != null) {
refreshWorker.cancel(true);
}
this.ingestJobs.clear();
setDataSource(null);
}
@Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
@ -252,19 +304,18 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
javax.swing.JScrollPane ingestModulesScrollPane = new javax.swing.JScrollPane();
ingestModuleTable = new javax.swing.JTable();
setMaximumSize(new java.awt.Dimension(32767, 32767));
setLayout(new java.awt.BorderLayout());
contentPanel.setMaximumSize(new java.awt.Dimension(32767, 32767));
contentPanel.setMinimumSize(new java.awt.Dimension(625, 150));
contentPanel.setPreferredSize(new java.awt.Dimension(625, 150));
contentPanel.setLayout(new java.awt.GridBagLayout());
ingestJobsScrollPane.setBorder(null);
ingestJobsScrollPane.setMinimumSize(new java.awt.Dimension(16, 16));
ingestJobsScrollPane.setPreferredSize(null);
ingestJobTable.setModel(ingestJobTableModel);
ingestJobTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
ingestJobTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
ingestJobTable.getTableHeader().setReorderingAllowed(false);
ingestJobsScrollPane.setViewportView(ingestJobTable);
ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
@ -300,6 +351,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
ingestModulesScrollPane.setPreferredSize(new java.awt.Dimension(254, 16));
ingestModuleTable.setModel(ingestModuleTableModel);
ingestModuleTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
ingestModuleTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
ingestModulesScrollPane.setViewportView(ingestModuleTable);
gridBagConstraints = new java.awt.GridBagConstraints();

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2018 Basis Technology Corp.
* Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.casemodule;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
@ -31,6 +30,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitJNI;
import org.sleuthkit.datamodel.TskCoreException;
@ -56,9 +56,9 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
private String drivePath;
private int sectorSize;
private String timeZone;
private Host host;
private ImageWriterSettings imageWriterSettings;
private boolean ignoreFatOrphanFiles;
private boolean setDataSourceOptionsCalled;
/**
* Constructs a local drive data source processor that implements the
@ -135,36 +135,56 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
if (!setDataSourceOptionsCalled) {
deviceId = UUID.randomUUID().toString();
drivePath = configPanel.getContentPath();
sectorSize = configPanel.getSectorSize();
timeZone = configPanel.getTimeZone();
ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
if (configPanel.getImageWriterEnabled()) {
imageWriterSettings = configPanel.getImageWriterSettings();
} else {
imageWriterSettings = null;
}
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. 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.
*
* @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
* to return results.
*/
@Override
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
deviceId = UUID.randomUUID().toString();
drivePath = configPanel.getContentPath();
sectorSize = configPanel.getSectorSize();
timeZone = configPanel.getTimeZone();
ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
if (configPanel.getImageWriterEnabled()) {
imageWriterSettings = configPanel.getImageWriterSettings();
} else {
imageWriterSettings = null;
}
this.host = host;
Image image;
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
new String[]{drivePath}, sectorSize,
timeZone, null, null, null, deviceId);
new String[]{drivePath}, sectorSize,
timeZone, null, null, null, deviceId, this.host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
}
}
addDiskTask = new AddImageTask(
new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings),
new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings),
progressMonitor,
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
new Thread(addDiskTask).start();
}
@ -220,19 +240,19 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
Image image;
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
new String[]{drivePath}, sectorSize,
timeZone, null, null, null, deviceId);
new String[]{drivePath}, sectorSize,
timeZone, null, null, null, deviceId);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
}
addDiskTask = new AddImageTask(new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings),
progressMonitor,
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
}
addDiskTask = new AddImageTask(new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings),
progressMonitor,
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
new Thread(addDiskTask).start();
}
@ -261,30 +281,5 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
drivePath = null;
timeZone = null;
ignoreFatOrphanFiles = false;
setDataSourceOptionsCalled = false;
}
/**
* Sets the configuration of the data source processor without using the
* configuration panel.
*
* @param drivePath Path to the local drive.
* @param timeZone The time zone to use when processing dates
* and times for the local drive, 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 drivePath, String timeZone, boolean ignoreFatOrphanFiles) {
this.deviceId = UUID.randomUUID().toString();
this.drivePath = drivePath;
this.sectorSize = 0;
this.timeZone = Calendar.getInstance().getTimeZone().getID();
this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
setDataSourceOptionsCalled = true;
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
/**
@ -58,7 +59,8 @@ final class LocalDiskPanel extends JPanel {
private static final long serialVersionUID = 1L;
private LocalDisk localDisk;
private boolean enableNext = false;
private final JFileChooser fc = new JFileChooser();
private JFileChooser fc;
private final JFileChooserFactory chooserHelper;
/**
* Creates new form LocalDiskPanel
@ -68,6 +70,7 @@ final class LocalDiskPanel extends JPanel {
customInit();
createTimeZoneList();
createSectorSizeList();
chooserHelper = new JFileChooserFactory();
}
/**
@ -261,6 +264,7 @@ final class LocalDiskPanel extends JPanel {
}//GEN-LAST:event_pathTextFieldKeyReleased
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
fc = chooserHelper.getChooser();
String oldText = pathTextField.getText();
// set the current directory of the FileChooser if the ImagePath Field is valid
File currentFile = new File(oldText);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -42,6 +42,8 @@ import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A local/logical files/logical evidence file(.lo1)/or directories data source
@ -76,7 +78,6 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
* when the deprecated method setDataSourceOptions is removed.
*/
private List<String> localFilePaths;
private boolean setDataSourceOptionsCalled;
/**
* Constructs a local/logical files and/or directories data source processor
@ -153,25 +154,44 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
if (!setDataSourceOptionsCalled) {
localFilePaths = configPanel.getContentPaths();
if (configPanel.subTypeIsLogicalEvidencePanel()) {
try {
//if the L01 option was chosen
localFilePaths = extractLogicalEvidenceFileContents(localFilePaths);
} catch (L01Exception ex) {
//contents of l01 could not be extracted don't add data source or run ingest
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Exception while getting open case.", ex);
return;
}
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. 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.
*
* @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
* to return results.
*/
@Override
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
localFilePaths = configPanel.getContentPaths();
if (configPanel.subTypeIsLogicalEvidencePanel()) {
try {
//if the L01 option was chosen
localFilePaths = extractLogicalEvidenceFileContents(localFilePaths);
} catch (L01Exception ex) {
//contents of l01 could not be extracted don't add data source or run ingest
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Exception while getting open case.", ex);
return;
}
}
run(UUID.randomUUID().toString(), configPanel.getFileSetName(), localFilePaths, progressMonitor, callback);
run(UUID.randomUUID().toString(), configPanel.getFileSetName(), localFilePaths, host, progressMonitor, callback);
}
/**
@ -197,7 +217,7 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
command.add("-f");
command.add("files");
command.add("-t");
File l01Dir = new File(Case.getCurrentCaseThrows().getModuleDirectory(), L01_EXTRACTION_DIR);
File l01Dir = new File(Case.getCurrentCaseThrows().getModuleDirectory(), L01_EXTRACTION_DIR);
if (!l01Dir.exists()) {
l01Dir.mkdirs();
}
@ -285,6 +305,34 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
return executablePath;
}
/**
* Adds a data source to the case database using a background task in a
* separate thread and the given settings instead of those provided by the
* 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.
*
* @param deviceId An ASCII-printable identifier for the
* device associated with the data source
* that is intended to be unique across
* multiple cases (e.g., a UUID).
* @param rootVirtualDirectoryName The name to give to the virtual directory
* that will serve as the root for the
* local/logical files and/or directories
* that compose the data source. Pass the
* empty string to get a default name of the
* form: LogicalFileSet[N]
* @param localFilePaths A list of local/logical file and/or
* directory localFilePaths.
* @param host The host for this data source.
* @param progressMonitor Progress monitor for reporting progress
* during processing.
* @param callback Callback to call when processing is done.
*/
public void run(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
new Thread(new AddLocalFilesTask(deviceId, rootVirtualDirectoryName, localFilePaths, host, progressMonitor, callback)).start();
}
/**
* Adds a data source to the case database using a background task in a
* separate thread and the given settings instead of those provided by the
@ -309,7 +357,7 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
* @param callback Callback to call when processing is done.
*/
public void run(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
new Thread(new AddLocalFilesTask(deviceId, rootVirtualDirectoryName, localFilePaths, progressMonitor, callback)).start();
run(deviceId, rootVirtualDirectoryName, localFilePaths, null, progressMonitor, callback);
}
/**
@ -334,7 +382,6 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
public void reset() {
configPanel.select();
localFilePaths = null;
setDataSourceOptionsCalled = false;
}
@Override
@ -368,29 +415,13 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
@Override
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
run(deviceId, "", filePaths, progressMonitor, callBack);
process(deviceId, dataSourcePath, null, progressMonitor, callBack);
}
/**
* Sets the configuration of the data source processor without using the
* configuration panel. The data source processor will assign a UUID to the
* data source and will use the time zone of the machine executing this code
* when when processing dates and times for the image.
*
* @param paths A list of local/logical file and/or directory
* localFilePaths.
*
* @deprecated Use the provided overload of the run method instead.
*/
@Deprecated
public void setDataSourceOptions(String paths) {
// The LocalFilesPanel used to separate file paths with a comma and pass
// them as a string, but because file names are allowed to contain
// commas, this approach was buggy and replaced. We now pass a list of
// String paths.
this.localFilePaths = Arrays.asList(paths.split(","));
setDataSourceOptionsCalled = true;
@Override
public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
run(deviceId, "", filePaths, host, progressMonitor, callBack);
}
/**

View File

@ -290,7 +290,7 @@ final class LocalFilesPanel extends javax.swing.JPanel {
final Case.CaseType currentCaseType = Case.getCurrentCaseThrows().getCaseType();
for (String currentPath : pathsList) {
if (!PathValidator.isValidForMultiUserCase(currentPath, currentCaseType)) {
if (!PathValidator.isValidForCaseType(currentPath, currentCaseType)) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.LocalFilesPanel_pathValidation_dataSourceOnCDriveError());
return;

View File

@ -191,7 +191,7 @@ final class LogicalEvidenceFilePanel extends javax.swing.JPanel implements Docum
}
// display warning if there is one (but don't disable "next" button)
try {
if (!PathValidator.isValidForMultiUserCase(path, Case.getCurrentCaseThrows().getCaseType())) {
if (!PathValidator.isValidForCaseType(path, Case.getCurrentCaseThrows().getCaseType())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.LogicalEvidenceFilePanel_pathValidation_dataSourceOnCDriveError());
return false;

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012-2018 Basis Technology Corp.
* Copyright 2012-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -32,6 +32,7 @@ import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.DriveUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
@ -45,7 +46,8 @@ class MissingImageDialog extends javax.swing.JDialog {
long obj_id;
SleuthkitCase db;
private final JFileChooser fileChooser = new JFileChooser();
private JFileChooser fileChooser;
private final JFileChooserFactory chooserHelper;
/**
* Instantiate a MissingImageDialog.
@ -58,17 +60,8 @@ class MissingImageDialog extends javax.swing.JDialog {
this.obj_id = obj_id;
this.db = db;
initComponents();
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
List<FileFilter> fileFiltersList = ImageDSProcessor.getFileFiltersList();
for (FileFilter fileFilter : fileFiltersList) {
fileChooser.addChoosableFileFilter(fileFilter);
}
fileChooser.setFileFilter(fileFiltersList.get(0));
chooserHelper = new JFileChooserFactory();
selectButton.setEnabled(false);
}
@ -270,6 +263,19 @@ class MissingImageDialog extends javax.swing.JDialog {
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
if(fileChooser == null) {
fileChooser = chooserHelper.getChooser();
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
List<FileFilter> fileFiltersList = ImageDSProcessor.getFileFiltersList();
for (FileFilter fileFilter : fileFiltersList) {
fileChooser.addChoosableFileFilter(fileFilter);
}
fileChooser.setFileFilter(fileFiltersList.get(0));
}
String oldText = pathNameTextField.getText();
lbWarning.setText("");
// set the current directory of the FileChooser if the ImagePath Field is valid

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -28,9 +28,9 @@ import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.PathValidator;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
/**
* The JPanel for the first page of the new case wizard.
@ -38,7 +38,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
private final JFileChooser fileChooser = new JFileChooser();
private final JFileChooserFactory fileChooserHelper = new JFileChooserFactory();
private final NewCaseWizardPanel1 wizPanel;
/**
@ -149,13 +149,22 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
private void validateSettings() {
/**
* Check the base case directory for the selected case type and show a
* warning if it is a dubious choice.
* warning if it is a dubious choice. For single user cases, disable
* the "Next" button if path is invalid.
*/
caseParentDirWarningLabel.setVisible(false);
String parentDir = getCaseParentDir();
if (!PathValidator.isValidForMultiUserCase(parentDir, getCaseType())) {
caseParentDirWarningLabel.setVisible(true);
caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnCDriveError.text"));
if (!PathValidator.isValidForCaseType(parentDir, getCaseType())) {
if (getCaseType() == CaseType.MULTI_USER_CASE) {
caseParentDirWarningLabel.setVisible(true);
caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnCDriveError.text"));
} else {
// disable the "Next" button
caseParentDirWarningLabel.setVisible(true);
caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.uncPath.error"));
wizPanel.setIsFinish(false);
return;
}
}
/**
@ -345,8 +354,9 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
* @param evt the action event
*/
private void caseDirBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseDirBrowseButtonActionPerformed
JFileChooser fileChooser = fileChooserHelper.getChooser();
fileChooser.setDragEnabled(false);
if (!caseParentDirTextField.getText().trim().equals("")) {
if (!caseParentDirTextField.getText().trim().isEmpty()) {
fileChooser.setCurrentDirectory(new File(caseParentDirTextField.getText()));
}
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

View File

@ -70,9 +70,7 @@ final class NewCaseWizardAction extends CallableSystemAction {
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
// Workaround to ensure new case dialog is not hidden on macOS
dialog.setAlwaysOnTop(true);
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor, WindowManager.getDefault().getMainWindow());
dialog.setVisible(true);
dialog.toFront();
if (wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION) {

View File

@ -55,10 +55,8 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
public NewCaseVisualPanel2 getComponent() {
if (component == null) {
component = new NewCaseVisualPanel2();
} else {
component.refreshCaseDetailsFields();
}
return component;
}
@ -137,6 +135,7 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
@Override
public void readSettings(WizardDescriptor settings) {
NewCaseVisualPanel2 panel = getComponent();
panel.refreshCaseDetailsFields();
try {
String lastExaminerName = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_EXAMINER_NAME);
String lastExaminerPhone = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_EXAMINER_PHONE);

View File

@ -58,7 +58,6 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel {
lbPointOfContactPhoneText.setVisible(false);
lbPointOfContactEmailLabel.setVisible(false);
lbPointOfContactEmailText.setVisible(false);
setUpCaseDetailsFields();
}
OptionalCasePropertiesPanel(boolean editCurrentCase) {

View File

@ -37,11 +37,8 @@ class SolrNotConfiguredDialog extends javax.swing.JDialog {
SolrNotConfiguredDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(), true);
// Center the startup window.
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
int width = getSize().width;
int height = getSize().height;
setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2);
initComponents();
setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
setIconImage(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/warning16.png", false));
}

View File

@ -18,12 +18,20 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Frame;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import org.netbeans.spi.sendopts.OptionProcessor;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.apputils.ResetWindowsAction;
import org.sleuthkit.autopsy.commandlineingest.CommandLineIngestManager;
import org.sleuthkit.autopsy.commandlineingest.CommandLineOpenCaseManager;
import org.sleuthkit.autopsy.commandlineingest.CommandLineOptionProcessor;
@ -61,19 +69,31 @@ public class StartupWindowProvider implements StartupWindowInterface {
return instance;
}
@NbBundle.Messages({
"# {0} - autFilePath",
"StartupWindowProvider.openCase.noFile=Unable to open previously open case because metadata file not found at: {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.cantOpen=Unable to open previously open case with metadata file: {0}"})
private void init() {
if (startupWindowToUse == null) {
// first check whether we are running from command line
if (isRunningFromCommandLine()) {
// or if we are running headless. Assume headless if the top level
// window is not visible.
boolean headless = !WindowManager.getDefault().getMainWindow().isVisible();
if (isRunningFromCommandLine() || headless) {
String defaultArg = getDefaultArgument();
if(defaultArg != null) {
new CommandLineOpenCaseManager(defaultArg).start();
return;
if (defaultArg != null) {
new CommandLineOpenCaseManager(defaultArg).start();
return;
} else {
// Autopsy is running from command line
logger.log(Level.INFO, "Running from command line"); //NON-NLS
startupWindowToUse = new CommandLineStartupWindow();
if(!headless) {
startupWindowToUse = new CommandLineStartupWindow();
}
// kick off command line processing
new CommandLineIngestManager().start();
return;
@ -83,36 +103,41 @@ public class StartupWindowProvider implements StartupWindowInterface {
if (RuntimeProperties.runningWithGUI()) {
checkSolr();
}
//discover the registered windows
Collection<? extends StartupWindowInterface> startupWindows
= Lookup.getDefault().lookupAll(StartupWindowInterface.class);
int windowsCount = startupWindows.size();
if (windowsCount == 1) {
startupWindowToUse = startupWindows.iterator().next();
logger.log(Level.INFO, "Will use the default startup window: " + startupWindowToUse.toString()); //NON-NLS
} else if (windowsCount == 2) {
//pick the non default one
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!org.sleuthkit.autopsy.casemodule.StartupWindow.class.isInstance(window)) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: " + startupWindowToUse.toString()); //NON-NLS
break;
switch (windowsCount) {
case 1:
startupWindowToUse = startupWindows.iterator().next();
logger.log(Level.INFO, "Will use the default startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
case 2: {
//pick the non default one
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!org.sleuthkit.autopsy.casemodule.StartupWindow.class.isInstance(window)) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
}
}
break;
}
} else {
// select first non-Autopsy start up window
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!window.getClass().getCanonicalName().startsWith("org.sleuthkit.autopsy")) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: " + startupWindowToUse.toString()); //NON-NLS
break;
default: {
// select first non-Autopsy start up window
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!window.getClass().getCanonicalName().startsWith("org.sleuthkit.autopsy")) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
}
}
break;
}
}
@ -121,6 +146,45 @@ public class StartupWindowProvider implements StartupWindowInterface {
startupWindowToUse = new org.sleuthkit.autopsy.casemodule.StartupWindow();
}
}
File openPreviousCaseFile = new File(ResetWindowsAction.getCaseToReopenFilePath());
if (openPreviousCaseFile.exists()) {
//do actual opening on another thread
new Thread(() -> {
String caseFilePath = "";
String unableToOpenMessage = null;
try {
//avoid readFileToString having ambiguous arguments
Charset encoding = null;
caseFilePath = FileUtils.readFileToString(openPreviousCaseFile, encoding);
if (new File(caseFilePath).exists()) {
FileUtils.forceDelete(openPreviousCaseFile);
//close the startup window as we attempt to open the case
close();
Case.openAsCurrentCase(caseFilePath);
} else {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_noFile(caseFilePath);
logger.log(Level.WARNING, unableToOpenMessage);
}
} catch (IOException ex) {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_deleteOpenFailure(ResetWindowsAction.getCaseToReopenFilePath());
logger.log(Level.WARNING, unableToOpenMessage, ex);
} catch (CaseActionException ex) {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_cantOpen(caseFilePath);
logger.log(Level.WARNING, unableToOpenMessage, ex);
}
if (RuntimeProperties.runningWithGUI() && !StringUtils.isBlank(unableToOpenMessage)) {
final String message = unableToOpenMessage;
SwingUtilities.invokeLater(() -> {
MessageNotifyUtil.Message.warn(message);
//the case was not opened restore the startup window
open();
});
}
}).start();
}
}
private void checkSolr() {
@ -147,9 +211,9 @@ public class StartupWindowProvider implements StartupWindowInterface {
* @return True if running from command line, false otherwise
*/
private boolean isRunningFromCommandLine() {
CommandLineOptionProcessor processor = Lookup.getDefault().lookup(CommandLineOptionProcessor.class);
if(processor != null) {
if (processor != null) {
return processor.isRunFromCommandLine();
}
return false;
@ -157,12 +221,12 @@ public class StartupWindowProvider implements StartupWindowInterface {
/**
* Get the default argument from the CommandLineOptionProcessor.
*
* @return If set, the default argument otherwise null.
*
* @return If set, the default argument otherwise null.
*/
private String getDefaultArgument() {
private String getDefaultArgument() {
CommandLineOptionProcessor processor = Lookup.getDefault().lookup(CommandLineOptionProcessor.class);
if(processor != null) {
if (processor != null) {
return processor.getDefaultArgument();
}
return null;

View File

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

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Host;
/**
* Application events published when hosts have been added to the Sleuth Kit
* data model for a case.
*/
public final class HostsAddedEvent extends HostsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when hosts have been added to
* the Sleuth Kit data model for a case.
*
* @param hosts The hosts that have been added.
*/
public HostsAddedEvent(List<Host> hosts) {
super(Case.Events.HOSTS_ADDED.name(), hosts);
}
}

View File

@ -0,0 +1,92 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Person;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Application events published when one or more hosts have been added to a
* person.
*/
public final class HostsAddedToPersonEvent extends TskDataModelChangedEvent<Person, Host> {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when one or more hosts have
* been added to a person.
*
* @param person The person.
* @param hosts The hosts.
*/
public HostsAddedToPersonEvent(Person person, List<Host> hosts) {
super(Case.Events.HOSTS_ADDED_TO_PERSON.toString(), Collections.singletonList(person), Person::getPersonId, hosts, Host::getHostId);
}
/**
* Gets the person.
*
* @return The person.
*/
public Person getPerson() {
return getOldValue().get(0);
}
/**
* Gets the hosts.
*
* @return The hosts.
*/
public List<Host> getHosts() {
return getNewValue();
}
@Override
protected List<Person> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<Person> persons = new ArrayList<>();
for (Long id : ids) {
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
if (person.isPresent()) {
persons.add(person.get());
}
}
return persons;
}
@Override
protected List<Host> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<Host> hosts = new ArrayList<>();
for (Long id : ids) {
Optional<Host> host = caseDb.getHostManager().getHostById(id);
if (host.isPresent()) {
hosts.add(host.get());
}
}
return hosts;
}
}

View File

@ -0,0 +1,51 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
/**
* Application events published when hosts have been deleted from the Sleuth
* Kit data model for a case.
*/
public final class HostsDeletedEvent extends TskDataModelObjectsDeletedEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when hosts have been deleted
* from the Sleuth Kit data model for a case.
*
* @param hostIds The host IDs of the deleted hosts.
*/
public HostsDeletedEvent(List<Long> hostIds) {
super(Case.Events.HOSTS_DELETED.name(), hostIds);
}
/**
* Gets the host IDs of the hosts that have been deleted.
*
* @return The host IDs.
*/
public List<Long> getHostIds() {
return getOldValue();
}
}

View File

@ -0,0 +1,69 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A base class for application events published when hosts in the Sleuth Kit
* data model for a case have been added or updated.
*/
public class HostsEvent extends TskDataModelChangedEvent<Host, Host> {
private static final long serialVersionUID = 1L;
/**
* Constructs the base class part of an application event published when
* hosts in the Sleuth Kit data model for a case have been added or updated.
*
* @param eventName The name of the Case.Events enum value for the event
* type.
* @param hosts The hosts.
*/
HostsEvent(String eventName, List<Host> hosts) {
super(eventName, null, null, hosts, Host::getHostId);
}
/**
* Gets the hosts that have been added or updated.
*
* @return The hosts.
*/
public List<Host> getHosts() {
return getNewValue();
}
@Override
protected List<Host> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<Host> hosts = new ArrayList<>();
for (Long id : ids) {
Optional<Host> host = caseDb.getHostManager().getHostById(id);
if (host.isPresent()) {
hosts.add(host.get());
}
}
return hosts;
}
}

View File

@ -0,0 +1,85 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Person;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Application events published when one or more hosts have been removed from a
* person.
*/
public class HostsRemovedFromPersonEvent extends TskDataModelChangedEvent<Person, Long> {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when one or more hosts have
* been removed from a person.
*
* @param person The person.
* @param hostIds The host IDs of the removed hosts.
*/
public HostsRemovedFromPersonEvent(Person person, List<Long> hostIds) {
super(Case.Events.HOSTS_REMOVED_FROM_PERSON.toString(), Collections.singletonList(person), Person::getPersonId, hostIds, (id -> id));
}
/**
* Gets the person.
*
* @return The person.
*/
public Person getPerson() {
return getOldValue().get(0);
}
/**
* Gets the host IDs of the removed hosts.
*
* @return The host IDs.
*/
public List<Long> getHostIds() {
return getNewValue();
}
@Override
protected List<Person> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<Person> persons = new ArrayList<>();
for (Long id : ids) {
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
if (person.isPresent()) {
persons.add(person.get());
}
}
return persons;
}
@Override
protected List<Long> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
return ids;
}
}

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Host;
/**
* Application events published when hosts in the Sleuth Kit data model for
* a case have been updated.
*/
public class HostsUpdatedEvent extends HostsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when hosts in the Sleuth Kit
* data model for a case have been updated.
*
* @param hosts The updated persons.
*/
public HostsUpdatedEvent(List<Host> hosts) {
super(Case.Events.HOSTS_UPDATED.name(), hosts);
}
}

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import static org.sleuthkit.autopsy.casemodule.Case.Events.OS_ACCOUNTS_ADDED;
import org.sleuthkit.datamodel.OsAccount;
/**
* An application event published when OS accounts are added to the Sleuth Kit
* data model for a case.
*/
public final class OsAccountsAddedEvent extends OsAccountsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when OS accounts are added to
* the Sleuth Kit data model for a case.
*
* @param osAccounts The OS accounts that were added.
*/
public OsAccountsAddedEvent(List<OsAccount> osAccounts) {
super(OS_ACCOUNTS_ADDED.toString(), osAccounts);
}
}

View File

@ -0,0 +1,51 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
/**
* An application event published when OS accounts have been deleted from the
* Sleuth Kit data model for a case.
*/
public final class OsAccountsDeletedEvent extends TskDataModelObjectsDeletedEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when OS accounts have been
* deleted from the Sleuth Kit data model for a case.
*
* @param osAccountObjectIds TSK object IDs of the deleted accounts.
*/
public OsAccountsDeletedEvent(List<Long> osAccountObjectIds) {
super(Case.Events.OS_ACCOUNTS_DELETED.toString(), osAccountObjectIds);
}
/**
* Gets the Sleuth Kit object IDs of the deleted OS accounts.
*
* @return The object IDs.
*/
List<Long> getOsAccountObjectIds() {
return getOldValue();
}
}

View File

@ -0,0 +1,66 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.List;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A base class for application events published when OS accounts in the Sleuth
* Kit data model for a case have been added or updated.
*/
class OsAccountsEvent extends TskDataModelChangedEvent<OsAccount, OsAccount> {
private static final long serialVersionUID = 1L;
/**
* Constructs the base class part of an application event published when
* OS accounts in the Sleuth Kit data model for a case have been added or
* updated.
*
* @param eventName The name of the Case.Events enum value for the event
* type.
* @param account The OS accounts.
*/
OsAccountsEvent(String eventName, List<OsAccount> osAccounts) {
super(eventName, null, null, osAccounts, OsAccount::getId);
}
/**
* Gets the OS accounts that have been added or updated.
*
* @return The OS accounts.
*/
public List<OsAccount> getOsAccounts() {
return getNewValue();
}
@Override
protected List<OsAccount> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<OsAccount> osAccounts = new ArrayList<>();
for (Long id : ids) {
osAccounts.add(caseDb.getOsAccountManager().getOsAccountByObjectId(id));
}
return osAccounts;
}
}

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.OsAccount;
/**
* An application event published when OS accounts in the Sleuth Kit data model
* for a case have been updated.
*/
public final class OsAccountsUpdatedEvent extends OsAccountsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when OS accounts in the Sleuth
* Kit data model for a case have been updated.
*
* @param osAccounts The OS accounts that were updated.
*/
public OsAccountsUpdatedEvent(List<OsAccount> osAccounts) {
super(Case.Events.OS_ACCOUNTS_UPDATED.toString(), osAccounts);
}
}

View File

@ -0,0 +1,59 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import static org.sleuthkit.autopsy.casemodule.Case.Events.OS_ACCT_INSTANCES_ADDED;
import org.sleuthkit.datamodel.OsAccountInstance;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* An application event published when OS account instances are added to the
* Sleuth Kit data model for a case.
*/
public final class OsAcctInstancesAddedEvent extends TskDataModelChangedEvent<OsAccountInstance, OsAccountInstance> {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when OS account instances are
* added to the Sleuth Kit data model for a case.
*
* @param osAcctInstances The OS account instances that were added.
*/
public OsAcctInstancesAddedEvent(List<OsAccountInstance> osAcctInstances) {
super(OS_ACCT_INSTANCES_ADDED.toString(), null, null, osAcctInstances, OsAccountInstance::getInstanceId);
}
/**
* Gets the OS account instances that have been added.
*
* @return The OS account instances.
*/
public List<OsAccountInstance> getOsAccountInstances() {
return getNewValue();
}
@Override
protected List<OsAccountInstance> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
return caseDb.getOsAccountManager().getOsAccountInstances(ids);
}
}

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Person;
/**
* An application event published when persons have been added to the Sleuth Kit
* data model for a case.
*/
public class PersonsAddedEvent extends PersonsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when persons have been added to
* the Sleuth Kit data model for a case.
*
* @param persons The persons that have been added.
*/
public PersonsAddedEvent(List<Person> persons) {
super(Case.Events.PERSONS_ADDED.name(), persons);
}
}

View File

@ -0,0 +1,51 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
/**
* Application events published when persons have been deleted from the Sleuth
* Kit data model for a case.
*/
public class PersonsDeletedEvent extends TskDataModelObjectsDeletedEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when persons have been deleted
* from the Sleuth Kit data model for a case.
*
* @param personIds The IDs of the persons that have been deleted.
*/
public PersonsDeletedEvent(List<Long> personIds) {
super(Case.Events.PERSONS_DELETED.name(), personIds);
}
/**
* Gets the person IDs of the persons that have been deleted.
*
* @return The person IDs.
*/
List<Long> getPersonIds() {
return getOldValue();
}
}

View File

@ -0,0 +1,70 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.sleuthkit.datamodel.Person;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A base class for application events published when persons in the Sleuth Kit
* data model for a case have been added or updated.
*/
public class PersonsEvent extends TskDataModelChangedEvent<Person, Person> {
private static final long serialVersionUID = 1L;
/**
* Constructs the base class part of an application event published when
* persons in the Sleuth Kit data model for a case have been added or
* updated.
*
* @param eventName The name of the Case.Events enum value for the event
* type.
* @param persons The persons.
*/
PersonsEvent(String eventName, List<Person> persons) {
super(eventName, null, null, persons, Person::getPersonId);
}
/**
* Gets the persons that have been added or updated.
*
* @return The persons.
*/
public List<Person> getPersons() {
return getNewValue();
}
@Override
protected List<Person> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<Person> persons = new ArrayList<>();
for (Long id : ids) {
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
if (person.isPresent()) {
persons.add(person.get());
}
}
return persons;
}
}

View File

@ -0,0 +1,43 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Person;
/**
* Application events published when persons in the Sleuth Kit data model for
* a case have been updated.
*/
public class PersonsUpdatedEvent extends PersonsEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when persons in the Sleuth Kit
* data model for a case have been updated.
*
* @param persons The updated persons.
*/
public PersonsUpdatedEvent(List<Person> persons) {
super(Case.Events.PERSONS_UPDATED.name(), persons);
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015-2018 Basis Technology Corp.
* Copyright 2015-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,70 +18,48 @@
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Event published when a report is added to a case.
* An application event published when a report is added to a case.
*/
public final class ReportAddedEvent extends AutopsyEvent implements Serializable {
public final class ReportAddedEvent extends TskDataModelChangedEvent<Report, Report> {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(DataSourceAddedEvent.class.getName());
private transient Report report;
/**
* Constructs an event published when a report is added to a case.
* Constructs an application event published when a report is added to a
* case.
*
* @param report The data source that was added.
* @param report The report that was added.
*/
public ReportAddedEvent(Report report) {
/**
* Putting the object id of the report into newValue to allow for lazy
* loading of the Report object.
*/
super(Case.Events.REPORT_ADDED.toString(), null, report.getId());
this.report = report;
super(Case.Events.REPORT_ADDED.toString(), null, null, Stream.of(report).collect(Collectors.toList()), Report::getId);
}
/**
* Gets the data source that was added.
* Gets the reoprt that was added to the case.
*
* @return The data source.
* @return The report.
*/
public Report getReport() {
List<Report> reports = getNewValue();
return reports.get(0);
}
@Override
public Object getNewValue() {
/**
* The report field is set in the constructor, but it is transient so it
* will become null when the event is serialized for publication over a
* network. Doing a lazy load of the Report object may save database
* round trips from other nodes since subscribers to this event are
* often not interested in the event data.
*/
if (null != report) {
return report;
}
try {
long id = (Long) super.getNewValue();
List<Report> reports = Case.getCurrentCaseThrows().getSleuthkitCase().getAllReports();
for (Report thisReport : reports) {
if (thisReport.getId() == id) {
report = thisReport;
break;
}
}
return report;
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Error doing lazy load for remote event", ex); //NON-NLS
return null;
}
protected List<Report> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
Long id = ids.get(0);
List<Report> reports = new ArrayList<>();
reports.add(caseDb.getReportById(id));
return reports;
}
}

View File

@ -0,0 +1,126 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TaggingManager;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A base class for TagName added and update events.
*/
public class TagNamesEvent extends TskDataModelChangedEvent<TagName, TagName> {
private static final long serialVersionUID = 1L;
/**
* Construct the base event for TagNames that have been added or updated.
*
* @param eventName The name of the event.
* @param tagNames The TagNames that have been modified.
*/
private TagNamesEvent(String eventName, List<TagName> tagNames) {
super(eventName, null, null, tagNames, TagName::getId);
}
/**
* Returns a list of the added or modified TagNames.
*
* @return The event list of TagNames.
*/
public List<TagName> getTagNames() {
return getNewValue();
}
@Override
protected List<TagName> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<TagName> tagNames = new ArrayList<>();
TaggingManager taggingMrg = caseDb.getTaggingManager();
for (Long id : ids) {
tagNames.add(taggingMrg.getTagName(id));
}
return tagNames;
}
/**
* Application events published when TagNames have been Added from the
* Sleuth Kit data model for a case.
*/
public static class TagNamesAddedEvent extends TagNamesEvent {
private static final long serialVersionUID = 1L;
/**
* Construct an application event published when TagNames have been
* added to the Sleuth Kit data model.
*
* @param tagNames The TagNames that have been added.
*/
public TagNamesAddedEvent(List<TagName> tagNames) {
super(Case.Events.TAG_NAMES_ADDED.name(), tagNames);
}
}
/**
* Application events published when TagNames have been updated from the
* Sleuth Kit data model for a case.
*/
public static class TagNamesUpdatedEvent extends TagNamesEvent {
private static final long serialVersionUID = 1L;
/**
* Construct an application event published when TagNames have been
* updated in the Sleuth Kit data model.
*
* @param tagNames The TagNames that have been updated.
*/
public TagNamesUpdatedEvent(List<TagName> tagNames) {
super(Case.Events.TAG_NAMES_UPDATED.name(), tagNames);
}
}
/**
* Application events published when TagNames have been deleted from the
* Sleuth Kit data model for a case.
*/
public static class TagNamesDeletedEvent extends TskDataModelObjectsDeletedEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when the TagNames have been
* deleted from the Sleuth Kit data model for a case.
*
* @param tagNameIds The IDs of the TagNames that have been deleted.
*/
public TagNamesDeletedEvent(List<Long> tagNameIds) {
super(Case.Events.TAG_NAMES_DELETED.name(), tagNameIds);
}
public List<Long> getTagNameIds() {
return getOldValue();
}
}
}

View File

@ -0,0 +1,103 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagSet;
import org.sleuthkit.datamodel.TaggingManager;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A base class for TagSet added and update events.
*/
public class TagSetsEvent extends TskDataModelChangedEvent<TagSet, TagSet> {
private static final long serialVersionUID = 1L;
/**
* Construct a new TagSetEvent.
*
* @param eventName
* @param tagSets
*/
private TagSetsEvent(String eventName, List<TagSet> tagSets) {
super(eventName, null, null, tagSets, TagSet::getId);
}
/**
* Returns a list of the TagSet objects that were added or modified for this
* event.
*
* @return A list of TagSet objects.
*/
public List<TagSet> getTagSets() {
return this.getNewValue();
}
@Override
protected List<TagSet> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
List<TagSet> tagSets = new ArrayList<>();
TaggingManager taggingMrg = caseDb.getTaggingManager();
for (Long id : ids) {
tagSets.add(taggingMrg.getTagSet(id));
}
return tagSets;
}
/**
* Application events published when TagSets have been Added from the Sleuth
* Kit data model for a case.
*/
public static class TagSetsAddedEvent extends TagSetsEvent {
private static final long serialVersionUID = 1L;
/**
* Construct an application event published when TagSetss have been
* added to the Sleuth Kit data model.
*
* @param tagSets The TagSets that have been added.
*/
public TagSetsAddedEvent(List<TagSet> tagSets) {
super(Case.Events.TAG_SETS_ADDED.name(), tagSets);
}
}
/**
* Application events published when TagSets have been deleted from the
* Sleuth Kit data model for a case.
*/
public static class TagSetsDeletedEvent extends TskDataModelObjectsDeletedEvent {
private static final long serialVersionUID = 1L;
/**
* Constructs an application event published when the TagSets have been
* deleted from the Sleuth Kit data model for a case.
*
* @param tagNameIds The IDs of the TagNames that have been deleted.
*/
public TagSetsDeletedEvent(List<Long> tagNameIds) {
super(Case.Events.TAG_SETS_DELETED.name(), tagNameIds);
}
}
}

View File

@ -0,0 +1,205 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* An abstract base class for application events published when one or more
* Sleuth Kit Data Model objects for a case change in some way.
*
* This class extends AutopsyEvent. The AutopsyEvent class extends
* PropertyChangeEvent to integrate with legacy use of JavaBeans
* PropertyChangeEvents and PropertyChangeListeners as an application event
* publisher-subcriber mechanism. Subclasses need to decide what constitutes
* "old" and "new" objects for them and are encouraged to provide getters for
* these values that do not require clients to cast the return values.
*
* The AutopsyEvent class implements Serializable to allow local event instances
* to be published to other Autopsy nodes over a network in serialized form. TSK
* Data Model objects are generally not serializable because they encapsulate a
* reference to a SleuthkitCase object that represents the case database and
* which has local JDBC Connection objects. For this reason, this class supports
* serialization of the unique numeric IDs (TSK object IDs, case database row
* IDs, etc.) of the subject TSK Data Model objects and the "reconstruction" of
* those objects on other Autopsy nodes by querying the case database by unique
* ID.
*
* @param <T> The Sleuth Kit Data Model object type of the "old" data model
* objects.
* @param <U> The Sleuth Kit Data Model object type of the "new" data model
* objects.
*/
public abstract class TskDataModelChangedEvent<T, U> extends AutopsyEvent {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(TskDataModelChangedEvent.class.getName());
private final boolean hasOldValue;
private final List<Long> oldValueIds;
private transient List<T> oldValueObjects;
private final boolean hasNewValue;
private final List<Long> newValueIds;
private transient List<U> newValueObjects;
/**
* Constructs the base class part for application events published when one
* or more Sleuth Kit Data Model objects for a case change in some way.
*
* @param eventName The event name.
* @param oldValueObjects A list of he Data Model objects that have been
* designated as the "old" objects in the event.
* May be null.
* @param oldValueGetIdMethod A method that can be applied to the "old" data
* model objects to get their unique numeric IDs
* (TSK object IDs, case database row IDs, etc.).
* May be null if there are no "old" objects.
* @param newValueObjects A list of he Data Model objects that have been
* designated as the "new" objects in the event.
* May be null.
* @param newValueGetIdMethod A method that can be applied to the "new" data
* model objects to get their unique numeric IDs
* (TSK object IDs, case database row IDs, etc.).
* May be null if there are no "new" objects.
*/
protected TskDataModelChangedEvent(String eventName, List<T> oldValueObjects, Function<T, Long> oldValueGetIdMethod, List<U> newValueObjects, Function<U, Long> newValueGetIdMethod) {
super(eventName, null, null);
oldValueIds = new ArrayList<>();
this.oldValueObjects = new ArrayList<>();
if (oldValueObjects != null) {
hasOldValue = true;
oldValueIds.addAll(oldValueObjects.stream()
.map(o -> oldValueGetIdMethod.apply(o))
.collect(Collectors.toList()));
this.oldValueObjects.addAll(oldValueObjects);
} else {
hasOldValue = false;
}
newValueIds = new ArrayList<>();
this.newValueObjects = new ArrayList<>();
if (newValueObjects != null) {
hasNewValue = true;
newValueIds.addAll(newValueObjects.stream()
.map(o -> newValueGetIdMethod.apply(o))
.collect(Collectors.toList()));
this.newValueObjects.addAll(newValueObjects);
} else {
hasNewValue = false;
}
}
/**
* Gets a list of the Data Model objects that have been designated as the
* "old" objects in the event.
*
* @return The list of the "old" data model objects. May be empty.
*/
@Override
public List<T> getOldValue() {
if (hasOldValue) {
if (oldValueObjects == null) {
try {
Case currentCase = Case.getCurrentCaseThrows();
SleuthkitCase caseDb = currentCase.getSleuthkitCase();
oldValueObjects = getOldValueObjects(caseDb, oldValueIds);
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting oldValue() TSK Data Model objects for %s event (%s)", getPropertyName(), getSourceType()), ex);
return Collections.emptyList();
}
}
return Collections.unmodifiableList(oldValueObjects);
} else {
return Collections.emptyList();
}
}
/**
* Gets a list of the Data Model objects that have been designated as the
* "new" objects in the event.
*
* @return The list of the "new" data model objects. May be empty.
*/
@Override
public List<U> getNewValue() {
if (hasNewValue) {
if (newValueObjects == null) {
try {
Case currentCase = Case.getCurrentCaseThrows();
SleuthkitCase caseDb = currentCase.getSleuthkitCase();
newValueObjects = getNewValueObjects(caseDb, newValueIds);
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting newValue() TSK Data Model objects for %s event (%s)", getPropertyName(), getSourceType()), ex);
return Collections.emptyList();
}
}
return Collections.unmodifiableList(newValueObjects);
} else {
return Collections.emptyList();
}
}
/**
* Reconstructs the "old" Sleuth Kit Data Model objects associated with this
* application event, if any, using the given unique numeric IDs (TSK object
* IDs, case database row IDs, etc.) to query the given case database.
*
* @param caseDb The case database.
* @param ids The unique, numeric IDs (TSK object IDs, case database row
* IDs, etc.) of the Sleuth Kit Data Model objects.
*
* @return The objects.
*
* @throws org.sleuthkit.datamodel.TskCoreException If there is an error
* getting the Sleuth Kit
* Data Model objects.
*/
protected List<T> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
return Collections.emptyList();
}
/**
* Reconstructs the "new" Sleuth Kit Data Model objects associated with this
* application event, if any, using the given unique numeric IDs (TSK object
* IDs, case database row IDs, etc.) to query the given case database.
*
* @param caseDb The case database.
* @param ids The unique, numeric IDs (TSK object IDs, case database row
* IDs, etc.) of the Sleuth Kit Data Model objects.
*
* @return The objects.
*
* @throws org.sleuthkit.datamodel.TskCoreException If there is an error
* getting the Sleuth Kit
* Data Model objects.
*/
protected List<U> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,60 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.events;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.sleuthkit.autopsy.events.AutopsyEvent;
/**
* An abstract base class for application events published when one or more
* Sleuth Kit Data Model objects for a case have been deleted.
*
* This class extends AutopsyEvent. The AutopsyEvent class extends
* PropertyChangeEvent to integrate with legacy use of JavaBeans
* PropertyChangeEvents and PropertyChangeListeners as an application event
* publisher-subcriber mechanism. Subclasses need to decide what constitutes
* "old" and "new" objects for them.
*
* For this class the "old" values are the unique numeric IDs (TSK object IDs,
* case database row IDs, etc.) of the deleted TSK Data Model objects. There are
* no "new" values. Subclasses are encouraged to provide less generic getters
* with descriptive names for the unique IDs than the override of the inherited
* getOldValue() method below. These getters can be implemented by delegating to
* getOldValue().
*/
public class TskDataModelObjectsDeletedEvent extends AutopsyEvent {
private static final long serialVersionUID = 1L;
private final List<Long> deletedObjectIds;
protected TskDataModelObjectsDeletedEvent(String eventName, List<Long> deletedObjectIds) {
super(eventName, null, null);
this.deletedObjectIds = new ArrayList<>();
this.deletedObjectIds.addAll(deletedObjectIds);
}
@Override
public List<Long> getOldValue() {
return Collections.unmodifiableList(deletedObjectIds);
}
}

View File

@ -23,25 +23,4 @@
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="caseTableScrollPane">
<Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[500, 500]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2017-2019 Basis Technology Corp.
* Copyright 2017-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.casemodule.multiusercasesbrowser;
import java.awt.BorderLayout;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -68,8 +69,7 @@ public final class MultiUserCasesBrowserPanel extends javax.swing.JPanel impleme
outlineView = new org.openide.explorer.view.OutlineView();
outline = this.outlineView.getOutline();
configureOutlineView();
caseTableScrollPane.add(outlineView);
caseTableScrollPane.setViewportView(outlineView);
add(outlineView, BorderLayout.CENTER);
this.setVisible(true);
}
@ -146,20 +146,11 @@ public final class MultiUserCasesBrowserPanel extends javax.swing.JPanel impleme
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
caseTableScrollPane = new javax.swing.JScrollPane();
setMinimumSize(new java.awt.Dimension(0, 5));
setPreferredSize(new java.awt.Dimension(5, 5));
setLayout(new java.awt.BorderLayout());
caseTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
caseTableScrollPane.setMinimumSize(new java.awt.Dimension(0, 5));
caseTableScrollPane.setOpaque(false);
caseTableScrollPane.setPreferredSize(new java.awt.Dimension(500, 500));
add(caseTableScrollPane, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane caseTableScrollPane;
// End of variables declaration//GEN-END:variables
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015-2019 Basis Technology Corp.
* Copyright 2015-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -56,7 +56,7 @@ public final class Blackboard implements Closeable {
@Deprecated
public synchronized void indexArtifact(BlackboardArtifact artifact) throws BlackboardException {
try {
Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifact(artifact, "");
Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifact(artifact, "", null);
} catch (org.sleuthkit.datamodel.Blackboard.BlackboardException ex) {
throw new BlackboardException(ex.getMessage(), ex);
}
@ -117,6 +117,7 @@ public final class Blackboard implements Closeable {
* @deprecated Do not use.
*/
@Deprecated
@Override
public void close() throws IOException {
/*
* No-op maintained for backwards compatibility. Clients should not

View File

@ -1,5 +1,5 @@
#Tue Aug 18 18:09:21 UTC 2020
OptionsCategory_Name_TagNamesOptions=\u30ab\u30b9\u30bf\u30e0\u30bf\u30b0
#Mon Jul 12 13:21:59 UTC 2021
OptionsCategory_Name_TagNamesOptions=\u30ab\u30b9\u30bf\u30e0\u30fb\u30bf\u30b0
OptionsCategory_TagNames=TagNames
TagNameDefinition.predefTagNames.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af
TagNameDefinition.predefTagNames.followUp.text=\u30d5\u30a9\u30ed\u30fc\u30a2\u30c3\u30d7
@ -11,14 +11,21 @@ TagNameDialog.JOptionPane.tagNameEmpty.title=\u7a7a(\u672a\u5165\u529b)\u306e\u7
TagNameDialog.JOptionPane.tagNameIllegalCharacters.message=\u30bf\u30b0\u540d\u306b\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u3089\u308c\u307e\u305b\u3093\: \\ \: * ? " < > | , ;
TagNameDialog.JOptionPane.tagNameIllegalCharacters.title=\u30bf\u30b0\u540d\u306b\u7121\u52b9\u306a\u6587\u5b57\u304c\u3042\u308a\u307e\u3059
TagNameDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
TagNameDialog.descriptionLabel.text=\u8aac\u660e\uff1a
TagNameDialog.editTitle.text=\u30bf\u30b0\u3092\u7de8\u96c6
TagNameDialog.newTagNameLabel.text=\u540d\u524d\:
TagNameDialog.notableCheckbox.text=\u30bf\u30b0\u306f\u30a2\u30a4\u30c6\u30e0\u304c\u6ce8\u76ee\u306b\u5024\u3059\u308b\u3053\u3068\u3092\u793a\u3057\u307e\u3059\u3002
TagNameDialog.okButton.text=OK
TagNameDialog.tagNameTextField.text=
TagNameDialog.title.text=\u65b0\u898f\u30bf\u30b0
TagOptionsPanel.TagNameDialog.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
TagOptionsPanel.TagNameDialog.tagNameAlreadyExists.title=\u30bf\u30b0\u540d\u3092\u8907\u88fd
TagOptionsPanel.deleteTagNameButton.text=\u30bf\u30b0\u3092\u524a\u9664
TagOptionsPanel.descriptionLabel.text=\u30bf\u30b0\u306e\u8aac\u660e\uff1a
TagOptionsPanel.editTagNameButton.text=\u30bf\u30b0\u306e\u7de8\u96c6
TagOptionsPanel.ingestRunningWarningLabel.text=\u53d6\u8fbc\u307f\u306e\u5b9f\u884c\u4e2d\u306f\u3001\u65e2\u5b58\u306e\u30bf\u30b0\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\u3002
TagOptionsPanel.isNotableLabel.text=\u30bf\u30b0\u306f\u30a2\u30a4\u30c6\u30e0\u304c\u6ce8\u76ee\u306b\u5024\u3059\u308b\u3053\u3068\u3092\u793a\u3057\u307e\u3059\uff1a
TagOptionsPanel.newTagNameButton.text=\u65b0\u898f\u30bf\u30b0
TagOptionsPanel.panelDescriptionTextArea.text=\u30bf\u30b0\u3092\u4f5c\u6210\u3068\u7ba1\u7406\u3002 \u30bf\u30b0\u306f\u3001\u30b1\u30fc\u30b9\u5185\u306e\u30d5\u30a1\u30a4\u30eb\u3068\u7d50\u679c\u306b\u9069\u7528\u3067\u304d\u307e\u3059\u3002 \u6ce8\u76ee\u306e\u30bf\u30b0\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u30bf\u30b0\u304c\u4ed8\u3051\u3089\u308c\u305f\u30a2\u30a4\u30c6\u30e0\u306b\u6ce8\u76ee\u306e\u30d5\u30e9\u30b0\u304c\u4ed8\u3051\u3089\u308c\u307e\u3059\u3002 \u30bf\u30b0\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u5909\u66f4\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u307f\u306b\u5f71\u97ff\u3057\u307e\u3059\u3002
TagOptionsPanel.tagTypesListLabel.text=\u30bf\u30b0\u540d\:
TagsManager.notableTagEnding.text=\ (\u9855\u8457)

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2012-2019 Basis Technology Corp.
* Copyright 2012-2021 Basis Technology Corp.
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
@ -36,6 +36,7 @@ import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalDirectory;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -59,7 +60,7 @@ import org.sleuthkit.datamodel.TskData;
public class FileManager implements Closeable {
private static final Logger LOGGER = Logger.getLogger(FileManager.class.getName());
private SleuthkitCase caseDb;
private final SleuthkitCase caseDb;
/**
* Constructs a manager that provides methods for retrieving files from the
@ -82,10 +83,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException If there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFilesByMimeType(Collection<String> mimeTypes) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFilesByMimeType(Collection<String> mimeTypes) throws TskCoreException {
return caseDb.findAllFilesWhere(createFileTypeInCondition(mimeTypes));
}
@ -101,10 +99,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException If there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFilesByParentPath(long dataSourceObjectID, String parentPath) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFilesByParentPath(long dataSourceObjectID, String parentPath) throws TskCoreException {
return caseDb.findAllFilesWhere(createParentPathCondition(dataSourceObjectID, parentPath));
}
@ -120,10 +115,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException If there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFilesByMimeType(Content dataSource, Collection<String> mimeTypes) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFilesByMimeType(Content dataSource, Collection<String> mimeTypes) throws TskCoreException {
return caseDb.findAllFilesWhere("data_source_obj_id = " + dataSource.getId() + " AND " + createFileTypeInCondition(mimeTypes));
}
@ -137,12 +129,8 @@ public class FileManager implements Closeable {
*
* @throws TskCoreException
*/
public synchronized List<AbstractFile> findFilesExactName(long parentId, String name) throws TskCoreException{
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
String whereClause = "name = '%s'";
return caseDb.findAllFilesInFolderWhere(parentId, String.format(whereClause, name));
public List<AbstractFile> findFilesExactName(long parentId, String name) throws TskCoreException{
return caseDb.getFileManager().findFilesExactName(parentId, name);
}
/**
@ -182,10 +170,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFiles(String fileName) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
@ -210,10 +195,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName, String parentSubString) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFiles(String fileName, String parentSubString) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
@ -236,16 +218,8 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName, AbstractFile parent) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName, parent));
}
return result;
public List<AbstractFile> findFiles(String fileName, AbstractFile parent) throws TskCoreException {
return caseDb.findFilesInFolder(fileName, parent);
}
/**
@ -262,10 +236,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException {
return caseDb.findFiles(dataSource, fileName);
}
@ -287,35 +258,10 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, String parentSubString) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> findFiles(Content dataSource, String fileName, String parentSubString) throws TskCoreException {
return caseDb.findFiles(dataSource, fileName, parentSubString);
}
/**
* Finds all files and directories with a given file name and given parent
* file or directory in a given data source (image, local/logical files set,
* etc.). The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
*
* @param dataSource The data source.
* @param fileName The full name or a pattern to match on part of the name
* @param parent The parent file or directory.
*
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return findFiles(dataSource, fileName, parent.getName());
}
/**
* Finds all files and directories with a given file name and path in a
@ -333,10 +279,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> openFiles(Content dataSource, String filePath) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<AbstractFile> openFiles(Content dataSource, String filePath) throws TskCoreException {
return caseDb.openFiles(dataSource, filePath);
}
@ -369,7 +312,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem adding the file to the
* case database.
*/
public synchronized DerivedFile addDerivedFile(String fileName,
public DerivedFile addDerivedFile(String fileName,
String localPath,
long size,
long ctime, long crtime, long atime, long mtime,
@ -377,9 +320,6 @@ public class FileManager implements Closeable {
Content parentObj,
String rederiveDetails, String toolName, String toolVersion, String otherDetails,
TskData.EncodingType encodingType) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return caseDb.addDerivedFile(fileName, localPath, size,
ctime, crtime, atime, mtime,
isFile, parentObj, rederiveDetails, toolName, toolVersion, otherDetails, encodingType);
@ -415,15 +355,12 @@ public class FileManager implements Closeable {
* @throws TskCoreException if there is a problem adding the file to the
* case database.
*/
public synchronized DerivedFile updateDerivedFile(DerivedFile derivedFile, String localPath,
public DerivedFile updateDerivedFile(DerivedFile derivedFile, String localPath,
long size,
long ctime, long crtime, long atime, long mtime,
boolean isFile, String mimeType,
String rederiveDetails, String toolName, String toolVersion, String otherDetails,
TskData.EncodingType encodingType) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return caseDb.updateDerivedFile(derivedFile, localPath, size,
ctime, crtime, atime, mtime,
isFile, mimeType, rederiveDetails, toolName, toolVersion, otherDetails, encodingType);
@ -440,10 +377,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException If there is a problem completing a case database
* operation.
*/
public synchronized List<LayoutFile> addCarvedFiles(CarvingResult carvingResult) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<LayoutFile> addCarvedFiles(CarvingResult carvingResult) throws TskCoreException {
return caseDb.addCarvedFiles(carvingResult);
}
@ -489,10 +423,41 @@ public class FileManager implements Closeable {
* @throws TskDataException if any of the local file paths is for a file or
* directory that does not exist or cannot be read.
*/
public synchronized LocalFilesDataSource addLocalFilesDataSource(String deviceId, String rootVirtualDirectoryName, String timeZone, List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException, TskDataException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public LocalFilesDataSource addLocalFilesDataSource(String deviceId, String rootVirtualDirectoryName, String timeZone, List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException, TskDataException {
return addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, timeZone, null, localFilePaths, progressUpdater);
}
/**
* Adds a set of local/logical files and/or directories to the case database
* as data source.
*
* @param deviceId An ASCII-printable identifier for the
* device associated with the data source
* that is intended to be unique across
* multiple cases (e.g., a UUID).
* @param rootVirtualDirectoryName The name to give to the virtual directory
* that will serve as the root for the
* local/logical files and/or directories
* that compose the data source. Pass the
* empty string to get a default name of the
* form: LogicalFileSet[N]
* @param timeZone The time zone used to process the data
* source, may be the empty string.
* @param host The host for this data source (may be null).
* @param localFilePaths A list of local/logical file and/or
* directory localFilePaths.
* @param progressUpdater Called after each file/directory is added
* to the case database.
*
* @return A local files data source object.
*
* @throws TskCoreException If there is a problem completing a database
* operation.
* @throws TskDataException if any of the local file paths is for a file or
* directory that does not exist or cannot be read.
*/
public LocalFilesDataSource addLocalFilesDataSource(String deviceId, String rootVirtualDirectoryName, String timeZone, Host host,
List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException, TskDataException {
List<java.io.File> localFiles = getFilesAndDirectories(localFilePaths);
CaseDbTransaction trans = null;
try {
@ -506,7 +471,7 @@ public class FileManager implements Closeable {
* children to the case database.
*/
trans = caseDb.beginTransaction();
LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans);
LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, host, trans);
List<AbstractFile> filesAdded = new ArrayList<>();
for (java.io.File localFile : localFiles) {
AbstractFile fileAdded = addLocalFile(trans, dataSource, localFile, TskData.EncodingType.NONE, progressUpdater);
@ -552,7 +517,7 @@ public class FileManager implements Closeable {
* @throws TskCoreException If there is a problem querying the case
* database.
*/
private static synchronized String generateFilesDataSourceName(SleuthkitCase caseDb) throws TskCoreException {
private static String generateFilesDataSourceName(SleuthkitCase caseDb) throws TskCoreException {
int localFileDataSourcesCounter = 0;
try {
List<VirtualDirectory> localFileDataSources = caseDb.getVirtualDirectoryRoots();
@ -643,13 +608,13 @@ public class FileManager implements Closeable {
*/
@Deprecated
@Override
public synchronized void close() throws IOException {
public void close() throws IOException {
/*
* No-op maintained for backwards compatibility. Clients should not
* attempt to close case services.
*/
}
}
/**
* Adds a set of local/logical files and/or directories to the case database
* as data source.
@ -669,10 +634,7 @@ public class FileManager implements Closeable {
* @deprecated Use addLocalFilesDataSource instead.
*/
@Deprecated
public synchronized VirtualDirectory addLocalFilesDirs(List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public VirtualDirectory addLocalFilesDirs(List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException {
try {
return addLocalFilesDataSource("", "", "", localFilePaths, progressUpdater).getRootDirectory();
} catch (TskDataException ex) {
@ -699,10 +661,7 @@ public class FileManager implements Closeable {
* carvingResult instead.
*/
@Deprecated
public synchronized LayoutFile addCarvedFile(String fileName, long fileSize, long parentObjId, List<TskFileRange> layout) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public LayoutFile addCarvedFile(String fileName, long fileSize, long parentObjId, List<TskFileRange> layout) throws TskCoreException {
Content parent = caseDb.getContentById(parentObjId);
List<CarvingResult.CarvedFile> carvedFiles = new ArrayList<>();
carvedFiles.add(new CarvingResult.CarvedFile(fileName, fileSize, layout));
@ -726,10 +685,7 @@ public class FileManager implements Closeable {
* carvingResult instead.
*/
@Deprecated
public synchronized List<LayoutFile> addCarvedFiles(List<org.sleuthkit.datamodel.CarvedFileContainer> filesToAdd) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
public List<LayoutFile> addCarvedFiles(List<org.sleuthkit.datamodel.CarvedFileContainer> filesToAdd) throws TskCoreException {
return caseDb.addCarvedFiles(filesToAdd);
}
@ -764,7 +720,7 @@ public class FileManager implements Closeable {
* @deprecated Use the version with explicit EncodingType instead
*/
@Deprecated
public synchronized DerivedFile addDerivedFile(String fileName,
public DerivedFile addDerivedFile(String fileName,
String localPath,
long size,
long ctime, long crtime, long atime, long mtime,
@ -798,5 +754,28 @@ public class FileManager implements Closeable {
private AbstractFile addLocalFile(CaseDbTransaction trans, SpecialDirectory parentDirectory, java.io.File localFile, FileAddProgressUpdater progressUpdater) throws TskCoreException {
return addLocalFile(trans, parentDirectory, localFile, TskData.EncodingType.NONE, progressUpdater);
}
/**
* Finds all files and directories with a given file name and given parent
* file or directory in a given data source (image, local/logical files set,
* etc.). The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
*
* @param dataSource The data source.
* @param fileName The full name or a pattern to match on part of the name
* @param parent The parent file or directory.
*
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*
* @deprecated Use version without the unnecessary dataSource argument
*/
@Deprecated
public List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
return findFiles(fileName, parent);
}
}

View File

@ -31,6 +31,7 @@ import javax.annotation.concurrent.Immutable;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.CentralRepoSettings;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.TagName;
@ -61,19 +62,19 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
private final TskData.FileKnown knownStatus;
private static final List<TagNameDefinition> STANDARD_TAGS_DEFINITIONS = new ArrayList<>();
private static final List<String> OLD_CATEGORY_TAG_NAMES = new ArrayList<>();
private static final List<String> PROJECT_VIC_NAMES_NO_LONGER_USED = new ArrayList<>();
static {
STANDARD_TAGS_DEFINITIONS.add(new TagNameDefinition(Bundle.TagNameDefinition_predefTagNames_bookmark_text(), "", TagName.HTML_COLOR.NONE, TskData.FileKnown.UNKNOWN));
STANDARD_TAGS_DEFINITIONS.add(new TagNameDefinition(Bundle.TagNameDefinition_predefTagNames_followUp_text(), "", TagName.HTML_COLOR.NONE, TskData.FileKnown.UNKNOWN));
STANDARD_TAGS_DEFINITIONS.add(new TagNameDefinition(Bundle.TagNameDefinition_predefTagNames_notableItem_text(), "", TagName.HTML_COLOR.NONE, TskData.FileKnown.BAD));
OLD_CATEGORY_TAG_NAMES.add("CAT-1: Child Exploitation (Illegal)");
OLD_CATEGORY_TAG_NAMES.add("CAT-2: Child Exploitation (Non-Illegal/Age Difficult)");
OLD_CATEGORY_TAG_NAMES.add("CAT-3: CGI/Animation (Child Exploitive)");
OLD_CATEGORY_TAG_NAMES.add("CAT-4: Exemplar/Comparison (Internal Use Only)");
OLD_CATEGORY_TAG_NAMES.add("CAT-5: Non-pertinent");
OLD_CATEGORY_TAG_NAMES.add("CAT-0: Uncategorized");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-1: Child Exploitation (Illegal)");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-2: Child Exploitation (Non-Illegal/Age Difficult)");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-3: CGI/Animation (Child Exploitive)");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-4: Exemplar/Comparison (Internal Use Only)");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-5: Non-pertinent");
PROJECT_VIC_NAMES_NO_LONGER_USED.add("CAT-0: Uncategorized");
}
/**
@ -236,7 +237,7 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
TagName saveToCase(SleuthkitCase caseDb) {
TagName tagName = null;
try {
tagName = caseDb.addOrUpdateTagName(displayName, description, color, knownStatus);
tagName = caseDb.getTaggingManager().addOrUpdateTagName(displayName, description, color, knownStatus);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error saving tag name definition", ex);
}
@ -259,7 +260,7 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
*/
static synchronized Set<TagNameDefinition> getTagNameDefinitions() {
if (needsVersionUpdate()) {
updateTagDefinitions();
updatePropertyFile();
}
String tagsProperty = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY);
@ -311,7 +312,7 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
/**
* Updates the Tag Definition file to the current format.
*/
private static void updateTagDefinitions() {
private static void updatePropertyFile() {
Integer version = getPropertyFileVersion();
List<TagNameDefinition> definitions = new ArrayList<>();
@ -355,18 +356,18 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
}
// Remove the standard and Project VIC tags from the list
List<String> tagStrings = new ArrayList<>();
List<String> tagStringsToKeep = new ArrayList<>();
List<String> standardTags = getStandardTagNames();
for (TagNameDefinition def : definitions) {
if (!standardTags.contains(def.getDisplayName())
&& !OLD_CATEGORY_TAG_NAMES.contains(def.getDisplayName())) {
tagStrings.add(def.toSettingsFormat());
&& !PROJECT_VIC_NAMES_NO_LONGER_USED.contains(def.getDisplayName())) {
tagStringsToKeep.add(def.toSettingsFormat());
}
}
// Write out the version and the new tag list.
ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_SETTING_VERSION_KEY, Integer.toString(TAG_SETTINGS_VERSION));
ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, String.join(";", tagStrings));
ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, String.join(";", tagStringsToKeep));
}
/**
@ -375,7 +376,7 @@ final public class TagNameDefinition implements Comparable<TagNameDefinition> {
* @return A list of tag names, or empty list if none were found.
*/
private static List<String> getCRNotableList() {
String notableTagsProp = ModuleSettings.getConfigSetting("CentralRepository", "db.badTags"); // NON-NLS
String notableTagsProp = ModuleSettings.getConfigSetting(CentralRepoSettings.getInstance().getModuleSettingsKey(), "db.badTags"); // NON-NLS
if (notableTagsProp != null && !notableTagsProp.isEmpty()) {
return Arrays.asList(notableTagsProp.split(","));
}

View File

@ -88,7 +88,7 @@ final public class TagSetDefinition {
}
/**
* Returns a list of the defined TagSet objects.
* Returns a list of configured TagSets (from the user's config folder)
*
* @return A list of TagSetDefinition objects or empty list if none were
* found.

View File

@ -18,9 +18,12 @@
*/
package org.sleuthkit.autopsy.casemodule.services;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@ -29,8 +32,11 @@ import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent;
import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesDeletedEvent;
import org.sleuthkit.autopsy.casemodule.services.contentviewertags.ContentViewerTagManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -55,9 +61,42 @@ public class TagsManager implements Closeable {
private static final Logger LOGGER = Logger.getLogger(TagsManager.class.getName());
private final SleuthkitCase caseDb;
private static String DEFAULT_TAG_SET_NAME = "Project VIC";
// NOTE: This name is also hard coded in Image Gallery and Projet Vic module.
// They need to stay in sync
private static String PROJECT_VIC_TAG_SET_NAME = "Project VIC";
private static final Object lock = new Object();
private final Map<String, TagName> allTagNameMap = Collections.synchronizedMap(new HashMap<>());
private final PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Case.Events.TAG_NAMES_ADDED.name())
|| evt.getPropertyName().equals(Case.Events.TAG_NAMES_UPDATED.name())) {
TagNamesEvent tagEvent = (TagNamesEvent) evt;
List<TagName> addTagNames = tagEvent.getTagNames();
for (TagName tag : addTagNames) {
allTagNameMap.put(tag.getDisplayName(), tag);
}
} else if (evt.getPropertyName().equals(Case.Events.TAG_NAMES_DELETED.name())) {
TagNamesDeletedEvent tagEvent = (TagNamesDeletedEvent) evt;
List<Long> deletedIds = tagEvent.getTagNameIds();
List<String> keysToRemove = new ArrayList<>();
for (TagName tagName : getAllTagNames()) {
if (deletedIds.contains(tagName.getId())) {
keysToRemove.add(tagName.getDisplayName());
}
}
for (String key : keysToRemove) {
allTagNameMap.remove(key);
}
}
}
};
private final PropertyChangeListener weakListener = WeakListeners.propertyChange(listener, null);
static {
@ -175,8 +214,6 @@ public class TagsManager implements Closeable {
/*
* No current case, nothing more to add to the set.
*/
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to get list of TagNames from TagsManager.", ex);
}
return tagDisplayNames;
}
@ -196,7 +233,7 @@ public class TagsManager implements Closeable {
try {
List<TagSet> tagSetList = Case.getCurrentCaseThrows().getSleuthkitCase().getTaggingManager().getTagSets();
for (TagSet tagSet : tagSetList) {
if (tagSet.getName().equals(DEFAULT_TAG_SET_NAME)) {
if (tagSet.getName().equals(PROJECT_VIC_TAG_SET_NAME)) {
for (TagName tagName : tagSet.getTagNames()) {
tagList.add(tagName.getDisplayName());
}
@ -237,7 +274,7 @@ public class TagsManager implements Closeable {
}
/**
* Creates a new TagSetDefinition file.
* Creates a new TagSetDefinition file that will be used for future cases
*
* @param tagSetDef The tag set definition.
*
@ -258,26 +295,34 @@ public class TagsManager implements Closeable {
TagsManager(SleuthkitCase caseDb) {
this.caseDb = caseDb;
// Add standard tags and the Project VIC default tag set and tags.
// Add standard tags and any configured tag sets.
TaggingManager taggingMgr = caseDb.getTaggingManager();
try {
List<TagSet> setList = taggingMgr.getTagSets();
if (setList.isEmpty()) {
List<TagSet> tagSetsInCase = taggingMgr.getTagSets();
if (tagSetsInCase.isEmpty()) {
// add the standard tag names
for (TagNameDefinition def : TagNameDefinition.getStandardTagNameDefinitions()) {
caseDb.addOrUpdateTagName(def.getDisplayName(), def.getDescription(), def.getColor(), def.getKnownStatus());
taggingMgr.addOrUpdateTagName(def.getDisplayName(), def.getDescription(), def.getColor(), def.getKnownStatus());
}
//Assume new case and add tag sets
//Assume new case and add all tag sets
for (TagSetDefinition setDef : TagSetDefinition.readTagSetDefinitions()) {
List<TagName> tagNameList = new ArrayList<>();
List<TagName> tagNamesInSet = new ArrayList<>();
for (TagNameDefinition tagNameDef : setDef.getTagNameDefinitions()) {
tagNameList.add(caseDb.addOrUpdateTagName(tagNameDef.getDisplayName(), tagNameDef.getDescription(), tagNameDef.getColor(), tagNameDef.getKnownStatus()));
tagNamesInSet.add(taggingMgr.addOrUpdateTagName(tagNameDef.getDisplayName(), tagNameDef.getDescription(), tagNameDef.getColor(), tagNameDef.getKnownStatus()));
}
if (!tagNameList.isEmpty()) {
taggingMgr.addTagSet(setDef.getName(), tagNameList);
if (!tagNamesInSet.isEmpty()) {
taggingMgr.addTagSet(setDef.getName(), tagNamesInSet);
}
}
}
for(TagName tagName: caseDb.getAllTagNames()) {
allTagNameMap.put(tagName.getDisplayName(), tagName);
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error updating standard tag name and tag set definitions", ex);
} catch (IOException ex) {
@ -287,6 +332,10 @@ public class TagsManager implements Closeable {
for (TagNameDefinition tagName : TagNameDefinition.getTagNameDefinitions()) {
tagName.saveToCase(caseDb);
}
Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_UPDATED), weakListener);
Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_ADDED), weakListener);
Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_DELETED), weakListener);
}
/**
@ -332,11 +381,12 @@ public class TagsManager implements Closeable {
* Gets a list of all tag names currently in the case database.
*
* @return A list, possibly empty, of TagName objects.
*
* @throws TskCoreException If there is an error querying the case database.
*/
public List<TagName> getAllTagNames() throws TskCoreException {
return caseDb.getAllTagNames();
public synchronized List<TagName> getAllTagNames() {
List<TagName> tagNames = new ArrayList<>();
tagNames.addAll(allTagNameMap.values());
return tagNames;
}
/**
@ -434,7 +484,7 @@ public class TagsManager implements Closeable {
*/
public Map<String, TagName> getDisplayNamesToTagNamesMap() throws TskCoreException {
Map<String, TagName> tagNames = new HashMap<>();
for (TagName tagName : caseDb.getAllTagNames()) {
for (TagName tagName : getAllTagNames()) {
tagNames.put(tagName.getDisplayName(), tagName);
}
return tagNames;
@ -516,13 +566,13 @@ public class TagsManager implements Closeable {
public TagName addTagName(String displayName, String description, TagName.HTML_COLOR color, TskData.FileKnown knownStatus) throws TagNameAlreadyExistsException, TskCoreException {
synchronized (lock) {
try {
TagName tagName = caseDb.addOrUpdateTagName(displayName, description, color, knownStatus);
TagName tagName = caseDb.getTaggingManager().addOrUpdateTagName(displayName, description, color, knownStatus);
Set<TagNameDefinition> customTypes = TagNameDefinition.getTagNameDefinitions();
customTypes.add(new TagNameDefinition(displayName, description, color, knownStatus));
TagNameDefinition.setTagNameDefinitions(customTypes);
return tagName;
} catch (TskCoreException ex) {
List<TagName> existingTagNames = caseDb.getAllTagNames();
List<TagName> existingTagNames = getAllTagNames();
for (TagName tagName : existingTagNames) {
if (tagName.getDisplayName().equals(displayName)) {
throw new TagNameAlreadyExistsException();
@ -1034,5 +1084,4 @@ public class TagsManager implements Closeable {
@Override
public void close() throws IOException {
}
}

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.centralrepository;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
@ -64,7 +65,13 @@ public final class AddEditCentralRepoCommentAction extends AbstractAction {
correlationAttributeInstance = CorrelationAttributeUtil.getCorrAttrForFile(file);
if (correlationAttributeInstance == null) {
addToDatabase = true;
correlationAttributeInstance = CorrelationAttributeUtil.makeCorrAttrFromFile(file);
final List<CorrelationAttributeInstance> md5CorrelationAttr = CorrelationAttributeUtil.makeCorrAttrsForSearch(file);
if (!md5CorrelationAttr.isEmpty()) {
//for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistency with other makeCorrAttrsForSearch methods per 7852
correlationAttributeInstance = md5CorrelationAttr.get(0);
} else {
correlationAttributeInstance = null;
}
}
if (file.getSize() == 0) {
putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentEmptyFile());

View File

@ -1,3 +1,12 @@
#Tue Aug 18 18:09:21 UTC 2020
OpenIDE-Module-Long-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u53d6\u8fbc\u30e2\u30b8\u30e5\u30fc\u30eb\u3068\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3002\n\n\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30dd\u30b8\u30c8\u30ea\u306e\u53d6\u8fbc\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3001\u9078\u629e\u3057\u305f\u76f8\u95a2\u30bf\u30a4\u30d7\u3068\u4e00\u81f4\u3059\u308b\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u5c5e\u6027\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4fdd\u5b58\u3057\u307e\u3059\u3002\n\u4fdd\u5b58\u3055\u308c\u305f\u5c5e\u6027\u306f\u3001\u4eca\u5f8c\u306e\u30b1\u30fc\u30b9\u3067\u3001\u53d6\u308a\u8fbc\u307f\u4e2d\u306b\u30d5\u30a1\u30a4\u30eb\u3068\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u95a2\u9023\u4ed8\u3051\u3066\u5206\u6790\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002\u300d
OpenIDE-Module-Short-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u8aad\u8fbc\u30e2\u30b8\u30e5\u30fc\u30eb
#Mon Jul 12 13:21:59 UTC 2021
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentEmptyFile=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6\uff08\u7a7a\u306e\u30d5\u30a1\u30a4\u30eb\uff09
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentNoMD5=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6\uff08MD5\u30cf\u30c3\u30b7\u30e5\u7121\u3057\uff09
CentralRepoCommentDialog.cancelButton.text=C&ancel
CentralRepoCommentDialog.commentLabel.text=\u30b3\u30e1\u30f3\u30c8\uff1a
CentralRepoCommentDialog.okButton.text=&OK
CentralRepoCommentDialog.title.addEditCentralRepoComment=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6
OpenIDE-Module-Display-Category=\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb
OpenIDE-Module-Long-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3068\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\n\n\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3001\u9078\u629e\u3057\u305f\u76f8\u95a2\u30bf\u30a4\u30d7\u306b\u4e00\u81f4\u3059\u308b\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u5c5e\u6027\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u683c\u7d0d\u3057\u307e\u3059\u3002\n\u4fdd\u5b58\u3055\u308c\u305f\u5c5e\u6027\u306f\u3001\u5c06\u6765\u306e\u30b1\u30fc\u30b9\u3067\u3001\u53d6\u308a\u8fbc\u307f\u4e2d\u306b\u30d5\u30a1\u30a4\u30eb\u3068\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u76f8\u4e92\u306b\u95a2\u9023\u4ed8\u3051\u3066\u5206\u6790\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002
OpenIDE-Module-Name=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
OpenIDE-Module-Short-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb

View File

@ -0,0 +1,112 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2022 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.centralrepository;
import java.io.File;
import java.nio.file.Paths;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/**
* Location for central repo settings and paths.
*/
public class CentralRepoSettings {
private static final CentralRepoSettings instance = new CentralRepoSettings();
/**
* @return The singleton instance of this class.
*/
public static CentralRepoSettings getInstance() {
return instance;
}
private static final String CENTRAL_REPOSITORY_FOLDER = "CentralRepository";
private static final String CENTRAL_REPOSITORY_SETTINGS_NAME = "CentralRepository";
private static final String CENTRAL_REPO_BASE_PATH = Paths.get(
PlatformUtil.getModuleConfigDirectory(),
CENTRAL_REPOSITORY_FOLDER).toString();
private static final String DEFAULT_DB_PARENT_PATH = Paths.get(CENTRAL_REPO_BASE_PATH, "LocalDatabase").toString();
private static final String DEFAULT_DB_NAME = "central_repository.db";
// NOTE: if this changes, an equivalent fix will be needed in CentralRepoDatamodelTest for the String PROPERTIES_FILE
private static final String MODULE_SETTINGS_KEY = Paths.get(
Paths.get(PlatformUtil.getUserConfigDirectory()).relativize(Paths.get(PlatformUtil.getModuleConfigDirectory())).toString(),
CENTRAL_REPOSITORY_FOLDER,
CENTRAL_REPOSITORY_SETTINGS_NAME).toString();
private static final String MODULE_SETTINGS_PROPERTIES = Paths.get(
CENTRAL_REPO_BASE_PATH,
CENTRAL_REPOSITORY_SETTINGS_NAME + ".properties").toString();
private static final String DATABASE_NAME_KEY = "db.sqlite.dbName"; //NON-NLS
private static final String DATABASE_PATH_KEY = "db.sqlite.dbDirectory"; //NON-NLS
/**
* @return The base path for central repository settings.
*/
public String getSettingsBaseFolder() {
return CENTRAL_REPO_BASE_PATH;
}
/**
* @return The module settings key that places the settings file within
* getSettingsBaseFolder.
*/
public String getModuleSettingsKey() {
return MODULE_SETTINGS_KEY;
}
/**
* @return The path to the central repo settings.
*/
public String getModuleSettingsFile() {
return MODULE_SETTINGS_PROPERTIES;
}
/**
* @return The default database parent path for sqlite cr.
*/
public String getDefaultDbPath() {
return DEFAULT_DB_PARENT_PATH;
}
/**
* @return The default sqlite database name.
*/
public String getDefaultDbName() {
return DEFAULT_DB_NAME;
}
/**
* @return The properties key for the sqlite database name in the settings.
*/
public String getDatabaseNameKey() {
return DATABASE_NAME_KEY;
}
/**
* @return The properties key for the sqlite database path in the settings.
*/
public String getDatabasePathKey() {
return DATABASE_PATH_KEY;
}
}

View File

@ -0,0 +1,8 @@
OtherOccurrences.csvHeader.attribute=Matched Attribute
OtherOccurrences.csvHeader.case=Case
OtherOccurrences.csvHeader.comment=Comment
OtherOccurrences.csvHeader.dataSource=Data Source
OtherOccurrences.csvHeader.device=Device
OtherOccurrences.csvHeader.known=Known
OtherOccurrences.csvHeader.path=Path
OtherOccurrences.csvHeader.value=Attribute Value

View File

@ -0,0 +1,9 @@
#Thu Sep 30 10:26:59 UTC 2021
OtherOccurrences.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u5c5e\u6027
OtherOccurrences.csvHeader.case=\u30b1\u30fc\u30b9
OtherOccurrences.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8
OtherOccurrences.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
OtherOccurrences.csvHeader.device=\u30c7\u30d0\u30a4\u30b9
OtherOccurrences.csvHeader.known=\u65e2\u77e5
OtherOccurrences.csvHeader.path=\u30d1\u30b9
OtherOccurrences.csvHeader.value=\u5c5e\u6027\u5024

View File

@ -0,0 +1,254 @@
/*
* Central Repository
*
* Copyright 2018-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.centralrepository.application;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskDataException;
/**
* Class for populating the Other Occurrences tab
*/
public class NodeData {
// For now hard code the string for the central repo files type, since
// getting it dynamically can fail.
private static final String FILE_TYPE_STR = "Files";
private static final String CSV_ITEM_SEPARATOR = "\",\"";
private final String caseName;
private String deviceID;
private String dataSourceName;
private final String filePath;
private final String typeStr;
private final String value;
private TskData.FileKnown known;
private String comment;
private AbstractFile originalAbstractFile = null;
private CorrelationAttributeInstance originalCorrelationInstance = null;
/**
* Create a node from a central repo instance.
*
* @param instance The central repo instance
* @param type The type of the instance
* @param value The value of the instance
*/
public NodeData(CorrelationAttributeInstance instance, CorrelationAttributeInstance.Type type, String value) {
caseName = instance.getCorrelationCase().getDisplayName();
deviceID = instance.getCorrelationDataSource().getDeviceID();
dataSourceName = instance.getCorrelationDataSource().getName();
filePath = instance.getFilePath();
this.typeStr = type.getDisplayName();
this.value = value;
known = instance.getKnownStatus();
comment = instance.getComment();
originalCorrelationInstance = instance;
}
/**
* Create a node from an abstract file.
*
* @param newFile The abstract file
* @param autopsyCase The current case
*
* @throws CentralRepoException
*/
NodeData(AbstractFile newFile, Case autopsyCase) throws CentralRepoException {
caseName = autopsyCase.getDisplayName();
try {
DataSource dataSource = autopsyCase.getSleuthkitCase().getDataSource(newFile.getDataSource().getId());
deviceID = dataSource.getDeviceId();
dataSourceName = dataSource.getName();
} catch (TskDataException | TskCoreException ex) {
throw new CentralRepoException("Error loading data source for abstract file ID " + newFile.getId(), ex);
}
filePath = newFile.getParentPath() + newFile.getName();
typeStr = FILE_TYPE_STR;
value = newFile.getMd5Hash();
known = newFile.getKnown();
comment = "";
originalAbstractFile = newFile;
}
/**
* Check if this node is a "file" type
*
* @return true if it is a file type
*/
boolean isFileType() {
return FILE_TYPE_STR.equals(typeStr);
}
/**
* Update the known status for this node
*
* @param newKnownStatus The new known status
*/
void updateKnown(TskData.FileKnown newKnownStatus) {
known = newKnownStatus;
}
/**
* Update the comment for this node
*
* @param newComment The new comment
*/
public void updateComment(String newComment) {
comment = newComment;
}
/**
* Get the case name
*
* @return the case name
*/
public String getCaseName() {
return caseName;
}
/**
* Get the device ID
*
* @return the device ID
*/
public String getDeviceID() {
return deviceID;
}
/**
* Get the data source name
*
* @return the data source name
*/
public String getDataSourceName() {
return dataSourceName;
}
/**
* Get the file path
*
* @return the file path
*/
public String getFilePath() {
return filePath;
}
/**
* Get the type (as a string)
*
* @return the type
*/
public String getType() {
return typeStr;
}
/**
* Get the value (MD5 hash for files)
*
* @return the value
*/
public String getValue() {
return value;
}
/**
* Get the known status
*
* @return the known status
*/
public TskData.FileKnown getKnown() {
return known;
}
/**
* Get the comment
*
* @return the comment
*/
public String getComment() {
return comment;
}
/**
* Get the backing abstract file. Should only be called if
* isCentralRepoNode() is false
*
* @return the original abstract file
*/
public AbstractFile getAbstractFile() throws CentralRepoException {
if (originalAbstractFile == null) {
throw new CentralRepoException("AbstractFile is null");
}
return originalAbstractFile;
}
/**
* Get the backing CorrelationAttributeInstance. Should only be called if
* isCentralRepoNode() is true
*
* @return the original CorrelationAttributeInstance
*
* @throws CentralRepoException
*/
public CorrelationAttributeInstance getCorrelationAttributeInstance() throws CentralRepoException {
if (originalCorrelationInstance == null) {
throw new CentralRepoException("CorrelationAttributeInstance is null");
}
return originalCorrelationInstance;
}
/**
* Get the string to append between elements when writing the node instance
* data to a CSV
*
* @return the CSV_ITEM_SEPARATOR string
*/
public static String getCsvItemSeparator() {
return CSV_ITEM_SEPARATOR;
}
/**
* Create a string representation of the node's data comma separated with a
* line separator ending
*
* @return a comma separated string representation of the node's data
*/
String toCsvString() {
StringBuilder line = new StringBuilder("\"");
line.append(getCaseName()).append(CSV_ITEM_SEPARATOR)
.append(getDataSourceName()).append(CSV_ITEM_SEPARATOR)
.append(getType()).append(CSV_ITEM_SEPARATOR)
.append(getValue()).append(CSV_ITEM_SEPARATOR)
.append(getKnown().toString()).append(CSV_ITEM_SEPARATOR)
.append(getFilePath()).append(CSV_ITEM_SEPARATOR)
.append(getComment()).append('"')
.append(System.getProperty("line.separator"));
return line.toString();
}
}

Some files were not shown because too many files have changed in this diff Show More