mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
initial commit
This commit is contained in:
parent
499f880632
commit
0c3394e88f
13
Core/ivy.xml
13
Core/ivy.xml
@ -1,3 +1,6 @@
|
|||||||
|
<!DOCTYPE ivy-module [
|
||||||
|
<!ENTITY httpcomponents.version "4.5.14">
|
||||||
|
]>
|
||||||
<ivy-module version="2.0">
|
<ivy-module version="2.0">
|
||||||
<info organisation="org.sleuthkit.autopsy" module="core"/>
|
<info organisation="org.sleuthkit.autopsy" module="core"/>
|
||||||
<configurations >
|
<configurations >
|
||||||
@ -72,6 +75,15 @@
|
|||||||
<!-- annotations like guarded by -->
|
<!-- annotations like guarded by -->
|
||||||
<dependency conf="core->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.6.0"/>
|
<dependency conf="core->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.6.0"/>
|
||||||
|
|
||||||
|
<dependency conf="core->default" org="com.license4j" name="license4j-runtime-library" rev="4.7.1"/>
|
||||||
|
|
||||||
|
<dependency conf="core->default" org="org.apache.httpcomponents" name="httpclient" rev="&httpcomponents.version;"/>
|
||||||
|
<dependency conf="core->default" org="org.apache.httpcomponents" name="httpmime" rev="&httpcomponents.version;"/>
|
||||||
|
<dependency conf="core->default" org="org.apache.httpcomponents" name="httpclient-win" rev="&httpcomponents.version;">
|
||||||
|
<exclude name="jna" />
|
||||||
|
<exclude name="jna-platform" />
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<override org="org.apache.zookeeper" module="zookeeper" rev="3.8.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="org.apache.zookeeper" module="zookeeper-jute" rev="3.8.0"/>
|
||||||
|
|
||||||
@ -84,5 +96,6 @@
|
|||||||
<override org="org.bouncycastle" module="bcprov-ext-jdk15on" rev="1.70"/>
|
<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="bcprov-jdk15on" rev="1.70"/>
|
||||||
<override org="org.bouncycastle" module="bcpkix-jdk15on" rev="1.70"/>
|
<override org="org.bouncycastle" module="bcpkix-jdk15on" rev="1.70"/>
|
||||||
|
<override org="junit" module="junit" rev="4.13.2"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</ivy-module>
|
</ivy-module>
|
||||||
|
@ -18,6 +18,7 @@ file.reference.bcprov-jdk15on-1.70.jar=release/modules/ext/bcprov-jdk15on-1.70.j
|
|||||||
file.reference.bcutil-jdk15on-1.70.jar=release/modules/ext/bcutil-jdk15on-1.70.jar
|
file.reference.bcutil-jdk15on-1.70.jar=release/modules/ext/bcutil-jdk15on-1.70.jar
|
||||||
file.reference.c3p0-0.9.5.5.jar=release/modules/ext/c3p0-0.9.5.5.jar
|
file.reference.c3p0-0.9.5.5.jar=release/modules/ext/c3p0-0.9.5.5.jar
|
||||||
file.reference.checker-qual-3.33.0.jar=release/modules/ext/checker-qual-3.33.0.jar
|
file.reference.checker-qual-3.33.0.jar=release/modules/ext/checker-qual-3.33.0.jar
|
||||||
|
file.reference.commons-codec-1.11.jar=release/modules/ext/commons-codec-1.11.jar
|
||||||
file.reference.commons-dbcp2-2.9.0.jar=release/modules/ext/commons-dbcp2-2.9.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-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-lang3-3.10.jar=release/modules/ext/commons-lang3-3.10.jar
|
||||||
@ -31,6 +32,10 @@ file.reference.decodetect-core-0.3.jar=release/modules/ext/decodetect-core-0.3.j
|
|||||||
file.reference.error_prone_annotations-2.18.0.jar=release/modules/ext/error_prone_annotations-2.18.0.jar
|
file.reference.error_prone_annotations-2.18.0.jar=release/modules/ext/error_prone_annotations-2.18.0.jar
|
||||||
file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.jar
|
file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.jar
|
||||||
file.reference.guava-32.0.1-jre.jar=release/modules/ext/guava-32.0.1-jre.jar
|
file.reference.guava-32.0.1-jre.jar=release/modules/ext/guava-32.0.1-jre.jar
|
||||||
|
file.reference.httpclient-4.5.14.jar=release/modules/ext/httpclient-4.5.14.jar
|
||||||
|
file.reference.httpclient-win-4.5.14.jar=release/modules/ext/httpclient-win-4.5.14.jar
|
||||||
|
file.reference.httpcore-4.4.16.jar=release/modules/ext/httpcore-4.4.16.jar
|
||||||
|
file.reference.httpmime-4.5.14.jar=release/modules/ext/httpmime-4.5.14.jar
|
||||||
file.reference.icepdf-core-6.2.2.jar=release/modules/ext/icepdf-core-6.2.2.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.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.istack-commons-runtime-3.0.11.jar=release/modules/ext/istack-commons-runtime-3.0.11.jar
|
||||||
@ -46,6 +51,7 @@ file.reference.javax.activation-api-1.2.0.jar=release/modules/ext/javax.activati
|
|||||||
file.reference.javax.ws.rs-api-2.1.1.jar=release/modules/ext/javax.ws.rs-api-2.1.1.jar
|
file.reference.javax.ws.rs-api-2.1.1.jar=release/modules/ext/javax.ws.rs-api-2.1.1.jar
|
||||||
file.reference.jaxb-api-2.3.1.jar=release/modules/ext/jaxb-api-2.3.1.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.jaxb-runtime-2.3.3.jar=release/modules/ext/jaxb-runtime-2.3.3.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.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.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.jgraphx-4.2.2.jar=release/modules/ext/jgraphx-4.2.2.jar
|
||||||
@ -55,6 +61,7 @@ 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.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.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.libphonenumber-8.12.45.jar=release/modules/ext/libphonenumber-8.12.45.jar
|
||||||
|
file.reference.license4j-runtime-library-4.7.1.jar=release/modules/ext/license4j-runtime-library-4.7.1.jar
|
||||||
file.reference.listenablefuture-1.0.jar=release/modules/ext/listenablefuture-1.0.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-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.logback-core-1.2.10.jar=release/modules/ext/logback-core-1.2.10.jar
|
||||||
|
@ -66,6 +66,14 @@
|
|||||||
<implementation-version/>
|
<implementation-version/>
|
||||||
</run-dependency>
|
</run-dependency>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<code-name-base>org.netbeans.modules.keyring</code-name-base>
|
||||||
|
<build-prerequisite/>
|
||||||
|
<compile-dependency/>
|
||||||
|
<run-dependency>
|
||||||
|
<specification-version>1.41</specification-version>
|
||||||
|
</run-dependency>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<code-name-base>org.netbeans.modules.options.api</code-name-base>
|
<code-name-base>org.netbeans.modules.options.api</code-name-base>
|
||||||
<build-prerequisite/>
|
<build-prerequisite/>
|
||||||
@ -165,14 +173,6 @@
|
|||||||
<specification-version>9.29</specification-version>
|
<specification-version>9.29</specification-version>
|
||||||
</run-dependency>
|
</run-dependency>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- <dependency>
|
|
||||||
<code-name-base>org.openide.filesystems.compat8</code-name-base>
|
|
||||||
<build-prerequisite/>
|
|
||||||
<compile-dependency/>
|
|
||||||
<run-dependency>
|
|
||||||
<specification-version>9.26</specification-version>
|
|
||||||
</run-dependency>
|
|
||||||
</dependency> -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<code-name-base>org.openide.filesystems.nb</code-name-base>
|
<code-name-base>org.openide.filesystems.nb</code-name-base>
|
||||||
<build-prerequisite/>
|
<build-prerequisite/>
|
||||||
@ -448,6 +448,10 @@
|
|||||||
<runtime-relative-path>ext/checker-qual-3.33.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/checker-qual-3.33.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/checker-qual-3.33.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/checker-qual-3.33.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</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>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/commons-dbcp2-2.9.0.jar</runtime-relative-path>
|
<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>
|
<binary-origin>release/modules/ext/commons-dbcp2-2.9.0.jar</binary-origin>
|
||||||
@ -500,6 +504,22 @@
|
|||||||
<runtime-relative-path>ext/guava-32.0.1-jre.jar</runtime-relative-path>
|
<runtime-relative-path>ext/guava-32.0.1-jre.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/guava-32.0.1-jre.jar</binary-origin>
|
<binary-origin>release/modules/ext/guava-32.0.1-jre.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/httpclient-4.5.14.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/httpclient-4.5.14.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/httpclient-win-4.5.14.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/httpclient-win-4.5.14.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/httpcore-4.4.16.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/httpcore-4.4.16.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/httpmime-4.5.14.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/httpmime-4.5.14.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/icepdf-core-6.2.2.jar</runtime-relative-path>
|
<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>
|
<binary-origin>release/modules/ext/icepdf-core-6.2.2.jar</binary-origin>
|
||||||
@ -560,6 +580,10 @@
|
|||||||
<runtime-relative-path>ext/jaxb-runtime-2.3.3.jar</runtime-relative-path>
|
<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>
|
<binary-origin>release/modules/ext/jaxb-runtime-2.3.3.jar</binary-origin>
|
||||||
</class-path-extension>
|
</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>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
|
<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>
|
||||||
@ -596,6 +620,10 @@
|
|||||||
<runtime-relative-path>ext/libphonenumber-8.12.45.jar</runtime-relative-path>
|
<runtime-relative-path>ext/libphonenumber-8.12.45.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/libphonenumber-8.12.45.jar</binary-origin>
|
<binary-origin>release/modules/ext/libphonenumber-8.12.45.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/license4j-runtime-library-4.7.1.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/license4j-runtime-library-4.7.1.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/listenablefuture-1.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/listenablefuture-1.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/listenablefuture-1.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/listenablefuture-1.0.jar</binary-origin>
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2020 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author rishwanth
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class CTCloudException extends Exception{
|
||||||
|
private final ErrorCode errorCode;
|
||||||
|
|
||||||
|
public enum ErrorCode {
|
||||||
|
BAD_REQUEST("CT-400", "Unknown or Bad request. Please contact Basis support at " + Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM + " for help diagnosing the problem."),
|
||||||
|
INVALID_KEY("CT-401", "An invalid license ID was used to access CyberTriage Cloud Service. Please contact Basis support " + Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM + " for help diagnosing the problem."),
|
||||||
|
GATEWAY_TIMEOUT("CT-504", "Request to CyberTriage Cloud Service timed out. Please retry after some time. If issue persists, please contact Basis support at " + Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM + " for assistance."),
|
||||||
|
UN_AUTHORIZED("CT-403", "An authorization error occurred. Please contact Basis support " + Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM + " for help diagnosing the problem."),
|
||||||
|
PROXY_UNAUTHORIZED("CT-407", "Proxy authentication failed. Please validate the connection settings from the Options panel Proxy Settings."),
|
||||||
|
TEMP_UNAVAILABLE("CT-500", "CyberTriage Cloud Service temporarily unavailable; please try again later. If this problem persists, contact Basis support at " + Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM),
|
||||||
|
UNKNOWN("CT-080", "Unknown error while communicating with CyberTriage Cloud Service. If this problem persists, contact Basis support at "+ Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM +" for assistance."),
|
||||||
|
UNKNOWN_HOST("CT-081", "Unknown host error. If this problem persists, contact Basis support at "+ Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM +" for assistance."),
|
||||||
|
NETWORK_ERROR("CT-015", "Error connecting to CyberTriage Cloud.\n"
|
||||||
|
+ "Check your firewall or proxy settings.\n"
|
||||||
|
+ "Contact Support (support@cybertriage.com) for further assistance");
|
||||||
|
private final String errorcode;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
private ErrorCode(String errorcode, String description) {
|
||||||
|
this.errorcode = errorcode;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return errorcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CTCloudException(CTCloudException.ErrorCode errorCode) {
|
||||||
|
super(errorCode.name());
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CTCloudException(CTCloudException.ErrorCode errorCode, Throwable throwable) {
|
||||||
|
super(errorCode.name(), throwable);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorCode getErrorCode() {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorDetails() {
|
||||||
|
if(getErrorCode() == CTCloudException.ErrorCode.UNKNOWN && Objects.nonNull(getCause())){
|
||||||
|
return String.format("Malware scan error %s occurred. Please try \"Re Scan\" from the dashboard to attempt Malware scaning again. "
|
||||||
|
+ "\nPlease contact Basis support at %s for help if the problem presists.",
|
||||||
|
StringUtils.isNotBlank(getCause().getLocalizedMessage()) ? "("+getCause().getLocalizedMessage()+")": "(Unknown)",
|
||||||
|
Constants.SUPPORT_AT_CYBERTRIAGE_DOT_COM );
|
||||||
|
}else {
|
||||||
|
return getErrorCode().getDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempts to find a more specific error code than "Unknown" for the given exception.
|
||||||
|
*/
|
||||||
|
public static ErrorCode parseUnknownException(Throwable throwable) {
|
||||||
|
|
||||||
|
String stackTrace = ExceptionUtils.getStackTrace(throwable);
|
||||||
|
if (stackTrace.contains("UnknownHostException")) {
|
||||||
|
return ErrorCode.UNKNOWN_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorCode.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2016 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// TODO take out anything sensitive or not used
|
||||||
|
final public class Constants {
|
||||||
|
|
||||||
|
public static final String CYBER_TRIAGE = "CyberTriage";
|
||||||
|
|
||||||
|
public static final String IS_MEMORY_IMAGE = "IS_MEMORY_IMAGE";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String SSLTEST_URL = "https://www2.cybertriage.com/ssl_test.html";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CT_CLOUD_SERVER = "https://rep1.cybertriage.com";
|
||||||
|
|
||||||
|
public static final String CT_CLOUD_DEV_SERVER = "https://cyber-triage-dev.appspot.com";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to watch demo video
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static final String DEMO_VIDEO_URL = "https://www.cybertriage.com/video/cyber-triage-demo-video/?utm_source=Cyber+Triage+Tool&utm_campaign=Eval+Demo+Video";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link request quote
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static final String REQUEST_QUOTE_URL = "https://www.cybertriage.com/request-quote/?utm_source=Cyber+Triage+Tool&utm_campaign=Eval+Quote";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Latest help document URL
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static final URI USER_GUIDE_LATEST_URL = URI.create("https://docs.cybertriage.com/en/latest/?utm_source=Cyber+Triage+Tool&utm_campaign=Help+Docs");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visit website URL
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static final String VISIT_WEBSITE_URL ="https://www.cybertriage.com/eval_data_202109/?utm_source=Cyber+Triage+Tool&utm_campaign=Eval+Data+Button";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL for visiting the website after the data is ingested on the dashboard.
|
||||||
|
*/
|
||||||
|
public static final String EVAL_WEBSITE_AUTO_URL = "https://www.cybertriage.com/eval_data_202109_auto/?utm_source=Cyber+Triage+Tool&utm_campaign=Eval+Data+Auto/"; //CT-4045
|
||||||
|
|
||||||
|
|
||||||
|
public static final String SUPPORT_AT_CYBERTRIAGE_DOT_COM = "support@cybertriage.com";
|
||||||
|
|
||||||
|
public static final String SALES_AT_CYBERTRIAGE_DOT_COM = "sales@cybertriage.com";
|
||||||
|
|
||||||
|
public final static String AUTODETECT = "Auto Detect";
|
||||||
|
|
||||||
|
public final static int RESTAPI_PORT = 9443;
|
||||||
|
|
||||||
|
public static final String INVALID_HOSTNAME_REQUEST = "Request rejected. Invalid host name. Hostname contains characters that are not allowed. \n"
|
||||||
|
+ "Characters that are not allowed include `~!@#$&^*(){}[]\\\\|;'\",<>/? \n"
|
||||||
|
+ "You may input the host IP address if the name is not resolving.";
|
||||||
|
public static final String INVALID_HOSTNAME_UI = "Invalid host name. Hostname contains characters that are not allowed. \n"
|
||||||
|
+ "Characters that are not allowed include `~!@#$&^*(){}[]\\\\|;'\",<>/?";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthTokenRequest;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthTokenResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileReputationResult;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseRequest;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.util.CTHostIDGenerationUtil;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.util.ObjectMapperUtil;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import java.util.List;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Data access layer for handling the CT api.
|
||||||
|
*/
|
||||||
|
public class CtApiDAO {
|
||||||
|
|
||||||
|
private static final String LICENSE_REQUEST_PATH = "/_ah/api/license/v1/activate";
|
||||||
|
private static final String AUTH_TOKEN_REQUEST_PATH = "/_ah/api/auth/v2/generate_token";
|
||||||
|
|
||||||
|
private static final CtApiDAO instance = new CtApiDAO();
|
||||||
|
private final ObjectMapper mapper = ObjectMapperUtil.getInstance().getDefaultObjectMapper();
|
||||||
|
|
||||||
|
private CtApiDAO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CtApiDAO getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getAppVersion() {
|
||||||
|
return Version.getName() + " " + Version.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T doPost(String urlPath, Object requestBody, Class<T> responseTypeRef) throws CTCloudException {
|
||||||
|
return null;
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseResponse getLicenseInfo(String licenseString) throws CTCloudException {
|
||||||
|
LicenseRequest licenseRequest = new LicenseRequest()
|
||||||
|
.setBoostLicenseCode(licenseString)
|
||||||
|
.setHostId(CTHostIDGenerationUtil.generateLicenseHostID())
|
||||||
|
.setProduct(getAppVersion());
|
||||||
|
|
||||||
|
return doPost(LICENSE_REQUEST_PATH, licenseRequest, LicenseResponse.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenResponse getAuthToken(String boostLicenseId) throws CTCloudException {
|
||||||
|
AuthTokenRequest authTokenRequest = new AuthTokenRequest()
|
||||||
|
.setAutopsyVersion(getAppVersion())
|
||||||
|
.setRequestFileUpload(true)
|
||||||
|
.setBoostLicenseId(boostLicenseId);
|
||||||
|
|
||||||
|
return doPost(AUTH_TOKEN_REQUEST_PATH, authTokenRequest, AuthTokenResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FileReputationResult> getReputationResults(String authToken, List<String> md5Hashes) throws CTCloudException {
|
||||||
|
// TODO
|
||||||
|
// return cloudServiceApi.lookupFileResults(md5Hashes, HashTypes.md5);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ResultType {
|
||||||
|
OK, SERVER_ERROR, NOT_AUTHORIZED
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,443 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.prefs.PreferenceChangeListener;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
import org.netbeans.api.keyring.Keyring;
|
||||||
|
import org.openide.util.*;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken from https://raw.githubusercontent.com/apache/netbeans/master/platform/o.n.core/src/org/netbeans/core/ProxySettings.java
|
||||||
|
* @author Jiri Rechtacek
|
||||||
|
*/
|
||||||
|
public class ProxySettings {
|
||||||
|
|
||||||
|
public static final String PROXY_HTTP_HOST = "proxyHttpHost"; // NOI18N
|
||||||
|
public static final String PROXY_HTTP_PORT = "proxyHttpPort"; // NOI18N
|
||||||
|
public static final String PROXY_HTTPS_HOST = "proxyHttpsHost"; // NOI18N
|
||||||
|
public static final String PROXY_HTTPS_PORT = "proxyHttpsPort"; // NOI18N
|
||||||
|
public static final String PROXY_SOCKS_HOST = "proxySocksHost"; // NOI18N
|
||||||
|
public static final String PROXY_SOCKS_PORT = "proxySocksPort"; // NOI18N
|
||||||
|
public static final String NOT_PROXY_HOSTS = "proxyNonProxyHosts"; // NOI18N
|
||||||
|
public static final String PROXY_TYPE = "proxyType"; // NOI18N
|
||||||
|
public static final String USE_PROXY_AUTHENTICATION = "useProxyAuthentication"; // NOI18N
|
||||||
|
public static final String PROXY_AUTHENTICATION_USERNAME = "proxyAuthenticationUsername"; // NOI18N
|
||||||
|
public static final String PROXY_AUTHENTICATION_PASSWORD = "proxyAuthenticationPassword"; // NOI18N
|
||||||
|
public static final String USE_PROXY_ALL_PROTOCOLS = "useProxyAllProtocols"; // NOI18N
|
||||||
|
public static final String DIRECT = "DIRECT"; // NOI18N
|
||||||
|
public static final String PAC = "PAC"; // NOI18N
|
||||||
|
|
||||||
|
public static final String SYSTEM_PROXY_HTTP_HOST = "systemProxyHttpHost"; // NOI18N
|
||||||
|
public static final String SYSTEM_PROXY_HTTP_PORT = "systemProxyHttpPort"; // NOI18N
|
||||||
|
public static final String SYSTEM_PROXY_HTTPS_HOST = "systemProxyHttpsHost"; // NOI18N
|
||||||
|
public static final String SYSTEM_PROXY_HTTPS_PORT = "systemProxyHttpsPort"; // NOI18N
|
||||||
|
public static final String SYSTEM_PROXY_SOCKS_HOST = "systemProxySocksHost"; // NOI18N
|
||||||
|
public static final String SYSTEM_PROXY_SOCKS_PORT = "systemProxySocksPort"; // NOI18N
|
||||||
|
public static final String SYSTEM_NON_PROXY_HOSTS = "systemProxyNonProxyHosts"; // NOI18N
|
||||||
|
public static final String SYSTEM_PAC = "systemPAC"; // NOI18N
|
||||||
|
|
||||||
|
// Only for testing purpose (Test connection in General options panel)
|
||||||
|
public static final String TEST_SYSTEM_PROXY_HTTP_HOST = "testSystemProxyHttpHost"; // NOI18N
|
||||||
|
public static final String TEST_SYSTEM_PROXY_HTTP_PORT = "testSystemProxyHttpPort"; // NOI18N
|
||||||
|
public static final String HTTP_CONNECTION_TEST_URL = "https://netbeans.apache.org";// NOI18N
|
||||||
|
|
||||||
|
private static String presetNonProxyHosts;
|
||||||
|
|
||||||
|
/** No proxy is used to connect. */
|
||||||
|
public static final int DIRECT_CONNECTION = 0;
|
||||||
|
|
||||||
|
/** Proxy setting is automatically detect in OS. */
|
||||||
|
public static final int AUTO_DETECT_PROXY = 1; // as default
|
||||||
|
|
||||||
|
/** Manually set proxy host and port. */
|
||||||
|
public static final int MANUAL_SET_PROXY = 2;
|
||||||
|
|
||||||
|
/** Proxy PAC file automatically detect in OS. */
|
||||||
|
public static final int AUTO_DETECT_PAC = 3;
|
||||||
|
|
||||||
|
/** Proxy PAC file manually set. */
|
||||||
|
public static final int MANUAL_SET_PAC = 4;
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ProxySettings.class.getName());
|
||||||
|
|
||||||
|
private static Preferences getPreferences() {
|
||||||
|
return NbPreferences.forModule (ProxySettings.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getHttpHost () {
|
||||||
|
return normalizeProxyHost (getPreferences ().get (PROXY_HTTP_HOST, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHttpPort () {
|
||||||
|
return getPreferences ().get (PROXY_HTTP_PORT, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHttpsHost () {
|
||||||
|
if (useProxyAllProtocols ()) {
|
||||||
|
return getHttpHost ();
|
||||||
|
} else {
|
||||||
|
return getPreferences ().get (PROXY_HTTPS_HOST, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHttpsPort () {
|
||||||
|
if (useProxyAllProtocols ()) {
|
||||||
|
return getHttpPort ();
|
||||||
|
} else {
|
||||||
|
return getPreferences ().get (PROXY_HTTPS_PORT, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSocksHost () {
|
||||||
|
if (useProxyAllProtocols ()) {
|
||||||
|
return getHttpHost ();
|
||||||
|
} else {
|
||||||
|
return getPreferences ().get (PROXY_SOCKS_HOST, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSocksPort () {
|
||||||
|
if (useProxyAllProtocols ()) {
|
||||||
|
return getHttpPort ();
|
||||||
|
} else {
|
||||||
|
return getPreferences ().get (PROXY_SOCKS_PORT, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNonProxyHosts () {
|
||||||
|
String hosts = getPreferences ().get (NOT_PROXY_HOSTS, getDefaultUserNonProxyHosts ());
|
||||||
|
return compactNonProxyHosts(hosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getProxyType () {
|
||||||
|
int type = getPreferences ().getInt (PROXY_TYPE, AUTO_DETECT_PROXY);
|
||||||
|
if (AUTO_DETECT_PROXY == type) {
|
||||||
|
type = ProxySettings.getSystemPac() != null ? AUTO_DETECT_PAC : AUTO_DETECT_PROXY;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getSystemHttpHost() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_HTTP_HOST, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemHttpPort() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_HTTP_PORT, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemHttpsHost() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_HTTPS_HOST, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemHttpsPort() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_HTTPS_PORT, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemSocksHost() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_SOCKS_HOST, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemSocksPort() {
|
||||||
|
return getPreferences().get(SYSTEM_PROXY_SOCKS_PORT, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemNonProxyHosts() {
|
||||||
|
return getPreferences().get(SYSTEM_NON_PROXY_HOSTS, getModifiedNonProxyHosts(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSystemPac() {
|
||||||
|
return getPreferences().get(SYSTEM_PAC, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getTestSystemHttpHost() {
|
||||||
|
return getPreferences().get(TEST_SYSTEM_PROXY_HTTP_HOST, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTestSystemHttpPort() {
|
||||||
|
return getPreferences().get(TEST_SYSTEM_PROXY_HTTP_PORT, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean useAuthentication () {
|
||||||
|
return getPreferences ().getBoolean (USE_PROXY_AUTHENTICATION, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean useProxyAllProtocols () {
|
||||||
|
return getPreferences ().getBoolean (USE_PROXY_ALL_PROTOCOLS, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAuthenticationUsername () {
|
||||||
|
return getPreferences ().get (PROXY_AUTHENTICATION_USERNAME, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char[] getAuthenticationPassword () {
|
||||||
|
String old = getPreferences().get(PROXY_AUTHENTICATION_PASSWORD, null);
|
||||||
|
if (old != null) {
|
||||||
|
getPreferences().remove(PROXY_AUTHENTICATION_PASSWORD);
|
||||||
|
setAuthenticationPassword(old.toCharArray());
|
||||||
|
}
|
||||||
|
char[] pwd = Keyring.read(PROXY_AUTHENTICATION_PASSWORD);
|
||||||
|
return pwd != null ? pwd : new char[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAuthenticationPassword(char[] password) {
|
||||||
|
Keyring.save(ProxySettings.PROXY_AUTHENTICATION_PASSWORD, password,
|
||||||
|
// XXX consider including getHttpHost and/or getHttpsHost
|
||||||
|
NbBundle.getMessage(ProxySettings.class, "ProxySettings.password.description")); // NOI18N
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addPreferenceChangeListener (PreferenceChangeListener l) {
|
||||||
|
getPreferences ().addPreferenceChangeListener (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removePreferenceChangeListener (PreferenceChangeListener l) {
|
||||||
|
getPreferences ().removePreferenceChangeListener (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPresetNonProxyHosts () {
|
||||||
|
if (presetNonProxyHosts == null) {
|
||||||
|
presetNonProxyHosts = System.getProperty ("http.nonProxyHosts", ""); // NOI18N
|
||||||
|
}
|
||||||
|
return presetNonProxyHosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDefaultUserNonProxyHosts () {
|
||||||
|
return getModifiedNonProxyHosts (getSystemNonProxyHosts ());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String concatProxies(String... proxies) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String n : proxies) {
|
||||||
|
if (n == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
n = n.trim();
|
||||||
|
if (n.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '|') { // NOI18N
|
||||||
|
if (!n.startsWith("|")) { // NOI18N
|
||||||
|
sb.append('|'); // NOI18N
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(n);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getModifiedNonProxyHosts (String systemPreset) {
|
||||||
|
String fromSystem = systemPreset.replace (";", "|").replace (",", "|"); //NOI18N
|
||||||
|
String fromUser = getPresetNonProxyHosts () == null ? "" : getPresetNonProxyHosts ().replace (";", "|").replace (",", "|"); //NOI18N
|
||||||
|
if (Utilities.isWindows ()) {
|
||||||
|
fromSystem = addReguralToNonProxyHosts (fromSystem);
|
||||||
|
}
|
||||||
|
final String staticNonProxyHosts = NbBundle.getMessage(ProxySettings.class, "StaticNonProxyHosts"); // NOI18N
|
||||||
|
String nonProxy = concatProxies(fromUser, fromSystem, staticNonProxyHosts); // NOI18N
|
||||||
|
String localhost;
|
||||||
|
try {
|
||||||
|
localhost = InetAddress.getLocalHost().getHostName();
|
||||||
|
if (!"localhost".equals(localhost)) { // NOI18N
|
||||||
|
nonProxy = nonProxy + "|" + localhost; // NOI18N
|
||||||
|
} else {
|
||||||
|
// Avoid this error when hostname == localhost:
|
||||||
|
// Error in http.nonProxyHosts system property: sun.misc.REException: localhost is a duplicate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (UnknownHostException e) {
|
||||||
|
// OK. Sometimes a hostname is assigned by DNS, but a computer
|
||||||
|
// is later pulled off the network. It may then produce a bogus
|
||||||
|
// name for itself which can't actually be resolved. Normally
|
||||||
|
// "localhost" is aliased to 127.0.0.1 anyway.
|
||||||
|
}
|
||||||
|
/* per Milan's agreement it's removed. See issue #89868
|
||||||
|
try {
|
||||||
|
String localhost2 = InetAddress.getLocalHost().getCanonicalHostName();
|
||||||
|
if (!"localhost".equals(localhost2) && !localhost2.equals(localhost)) { // NOI18N
|
||||||
|
nonProxy = nonProxy + "|" + localhost2; // NOI18N
|
||||||
|
} else {
|
||||||
|
// Avoid this error when hostname == localhost:
|
||||||
|
// Error in http.nonProxyHosts system property: sun.misc.REException: localhost is a duplicate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (UnknownHostException e) {
|
||||||
|
// OK. Sometimes a hostname is assigned by DNS, but a computer
|
||||||
|
// is later pulled off the network. It may then produce a bogus
|
||||||
|
// name for itself which can't actually be resolved. Normally
|
||||||
|
// "localhost" is aliased to 127.0.0.1 anyway.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return compactNonProxyHosts (nonProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// avoid duplicate hosts
|
||||||
|
private static String compactNonProxyHosts (String hosts) {
|
||||||
|
StringTokenizer st = new StringTokenizer(hosts, ","); //NOI18N
|
||||||
|
StringBuilder nonProxyHosts = new StringBuilder();
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
String h = st.nextToken().trim();
|
||||||
|
if (h.length() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nonProxyHosts.length() > 0) {
|
||||||
|
nonProxyHosts.append("|"); // NOI18N
|
||||||
|
}
|
||||||
|
nonProxyHosts.append(h);
|
||||||
|
}
|
||||||
|
st = new StringTokenizer (nonProxyHosts.toString(), "|"); //NOI18N
|
||||||
|
Set<String> set = new HashSet<String> ();
|
||||||
|
StringBuilder compactedProxyHosts = new StringBuilder();
|
||||||
|
while (st.hasMoreTokens ()) {
|
||||||
|
String t = st.nextToken ();
|
||||||
|
if (set.add (t.toLowerCase (Locale.US))) {
|
||||||
|
if (compactedProxyHosts.length() > 0) {
|
||||||
|
compactedProxyHosts.append('|'); // NOI18N
|
||||||
|
}
|
||||||
|
compactedProxyHosts.append(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compactedProxyHosts.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String addReguralToNonProxyHosts (String nonProxyHost) {
|
||||||
|
StringTokenizer st = new StringTokenizer (nonProxyHost, "|"); // NOI18N
|
||||||
|
StringBuilder reguralProxyHosts = new StringBuilder();
|
||||||
|
while (st.hasMoreTokens ()) {
|
||||||
|
String t = st.nextToken ();
|
||||||
|
if (t.indexOf ('*') == -1) { //NOI18N
|
||||||
|
t = t + '*'; //NOI18N
|
||||||
|
}
|
||||||
|
if (reguralProxyHosts.length() > 0)
|
||||||
|
reguralProxyHosts.append('|'); // NOI18N
|
||||||
|
reguralProxyHosts.append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reguralProxyHosts.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String normalizeProxyHost (String proxyHost) {
|
||||||
|
if (proxyHost.toLowerCase (Locale.US).startsWith ("http://")) { // NOI18N
|
||||||
|
return proxyHost.substring (7, proxyHost.length ());
|
||||||
|
} else {
|
||||||
|
return proxyHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InetSocketAddress analyzeProxy(URI uri) {
|
||||||
|
Parameters.notNull("uri", uri); // NOI18N
|
||||||
|
List<Proxy> proxies = ProxySelector.getDefault().select(uri);
|
||||||
|
assert proxies != null : "ProxySelector cannot return null for " + uri; // NOI18N
|
||||||
|
assert !proxies.isEmpty() : "ProxySelector cannot return empty list for " + uri; // NOI18N
|
||||||
|
String protocol = uri.getScheme();
|
||||||
|
Proxy p = proxies.get(0);
|
||||||
|
if (Proxy.Type.DIRECT == p.type()) {
|
||||||
|
// return null for DIRECT proxy
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (protocol == null
|
||||||
|
|| ((protocol.startsWith("http") || protocol.equals("ftp")) && Proxy.Type.HTTP == p.type()) // NOI18N
|
||||||
|
|| !(protocol.startsWith("http") || protocol.equals("ftp"))) { // NOI18N
|
||||||
|
if (p.address() instanceof InetSocketAddress) {
|
||||||
|
// check is
|
||||||
|
//assert ! ((InetSocketAddress) p.address()).isUnresolved() : p.address() + " must be resolved address.";
|
||||||
|
return (InetSocketAddress) p.address();
|
||||||
|
} else {
|
||||||
|
LOGGER.log(Level.INFO, p.address() + " is not instanceof InetSocketAddress but " + p.address().getClass()); // NOI18N
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reload() {
|
||||||
|
Reloader reloader = Lookup.getDefault().lookup(Reloader.class);
|
||||||
|
reloader.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ServiceProvider(service = NetworkSettings.ProxyCredentialsProvider.class, position = 1000)
|
||||||
|
public static class NbProxyCredentialsProvider extends NetworkSettings.ProxyCredentialsProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProxyHost(URI u) {
|
||||||
|
if (getPreferences() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
InetSocketAddress sa = analyzeProxy(u);
|
||||||
|
return sa == null ? null : sa.getHostName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProxyPort(URI u) {
|
||||||
|
if (getPreferences() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
InetSocketAddress sa = analyzeProxy(u);
|
||||||
|
return sa == null ? null : Integer.toString(sa.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getProxyUserName(URI u) {
|
||||||
|
if (getPreferences() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ProxySettings.getAuthenticationUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected char[] getProxyPassword(URI u) {
|
||||||
|
if (getPreferences() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ProxySettings.getAuthenticationPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isProxyAuthentication(URI u) {
|
||||||
|
if (getPreferences() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getPreferences().getBoolean(USE_PROXY_AUTHENTICATION, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A bridge between <code>o.n.core</code> and <code>core.network</code>.
|
||||||
|
* An implementation of this class brings a facility to reload Network Proxy Settings
|
||||||
|
* from underlying OS.
|
||||||
|
* The module <code>core.network</code> provides a implementation which may be accessible
|
||||||
|
* via <code>Lookup.getDefault()</code>. It's not guaranteed any implementation is found on all distribution.
|
||||||
|
*
|
||||||
|
* @since 3.40
|
||||||
|
*/
|
||||||
|
public abstract static class Reloader {
|
||||||
|
|
||||||
|
/** Reloads Network Proxy Settings from underlying system.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract void reload();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POJO for an auth token request.
|
||||||
|
*/
|
||||||
|
public class AuthTokenRequest {
|
||||||
|
|
||||||
|
@JsonProperty("autopsy_version")
|
||||||
|
private String autopsyVersion;
|
||||||
|
|
||||||
|
@JsonProperty("boost_license_id")
|
||||||
|
private String boostLicenseId;
|
||||||
|
|
||||||
|
@JsonProperty("requestFileUpload")
|
||||||
|
private boolean requestFileUpload;
|
||||||
|
|
||||||
|
public String getAutopsyVersion() {
|
||||||
|
return autopsyVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenRequest setAutopsyVersion(String autopsyVersion) {
|
||||||
|
this.autopsyVersion = autopsyVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBoostLicenseId() {
|
||||||
|
return boostLicenseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenRequest setBoostLicenseId(String boostLicenseId) {
|
||||||
|
this.boostLicenseId = boostLicenseId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequestFileUpload() {
|
||||||
|
return requestFileUpload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenRequest setRequestFileUpload(boolean requestFileUpload) {
|
||||||
|
this.requestFileUpload = requestFileUpload;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POJO for an auth token response.
|
||||||
|
*/
|
||||||
|
public class AuthTokenResponse {
|
||||||
|
private final String token;
|
||||||
|
private final String apiKey;
|
||||||
|
private final Long hashLookupCount;
|
||||||
|
private final Long hashLookupLimit;
|
||||||
|
private final Long fileUploadLimit;
|
||||||
|
private final Long fileUploadCount;
|
||||||
|
private final String fileUploadUrl;
|
||||||
|
private final ZonedDateTime expiration;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public AuthTokenResponse(
|
||||||
|
@JsonProperty("token") String token,
|
||||||
|
@JsonProperty("api_key") String apiKey,
|
||||||
|
@JsonProperty("hashLookupCount") Long hashLookupCount,
|
||||||
|
@JsonProperty("hashLookupLimit") Long hashLookupLimit,
|
||||||
|
@JsonProperty("fileUploadLimit") Long fileUploadLimit,
|
||||||
|
@JsonProperty("fileUploadCount") Long fileUploadCount,
|
||||||
|
@JsonProperty("fileUploadUrl") String fileUploadUrl,
|
||||||
|
@JsonProperty("expiration") ZonedDateTime expiration
|
||||||
|
) {
|
||||||
|
this.token = token;
|
||||||
|
this.apiKey = apiKey;
|
||||||
|
this.hashLookupCount = hashLookupCount;
|
||||||
|
this.hashLookupLimit = hashLookupLimit;
|
||||||
|
this.fileUploadLimit = fileUploadLimit;
|
||||||
|
this.fileUploadCount = fileUploadCount;
|
||||||
|
this.fileUploadUrl = fileUploadUrl;
|
||||||
|
this.expiration = expiration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiKey() {
|
||||||
|
return apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getHashLookupCount() {
|
||||||
|
return hashLookupCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getHashLookupLimit() {
|
||||||
|
return hashLookupLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFileUploadLimit() {
|
||||||
|
return fileUploadLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFileUploadCount() {
|
||||||
|
return fileUploadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileUploadUrl() {
|
||||||
|
return fileUploadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getExpiration() {
|
||||||
|
return expiration;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POJO for a boost license response object that is a part of the license
|
||||||
|
* response.
|
||||||
|
*/
|
||||||
|
public class BoostLicenseResponse {
|
||||||
|
|
||||||
|
private final String version;
|
||||||
|
private final String iv;
|
||||||
|
private final String encryptedKey;
|
||||||
|
private final String encryptedJson;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public BoostLicenseResponse(
|
||||||
|
@JsonProperty("version") String version,
|
||||||
|
@JsonProperty("iv") String iv,
|
||||||
|
@JsonProperty("encryptedKey") String encryptedKey,
|
||||||
|
@JsonProperty("encryptedJson") String encryptedJson) {
|
||||||
|
|
||||||
|
this.version = version;
|
||||||
|
this.iv = iv;
|
||||||
|
this.encryptedKey = encryptedKey;
|
||||||
|
this.encryptedJson = encryptedJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIv() {
|
||||||
|
return iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncryptedKey() {
|
||||||
|
return encryptedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncryptedJson() {
|
||||||
|
return encryptedJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2014 - 2016 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import org.sleuthkit.datamodel.Score;
|
||||||
|
import org.sleuthkit.datamodel.Score.Priority;
|
||||||
|
import org.sleuthkit.datamodel.Score.Significance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Score class represents a conclusion and the relative confidence in the conclusion about
|
||||||
|
* a subject. A subject may be an Item, a category/analysis result etc.
|
||||||
|
* @since 1.7.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum CTScore {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Enum names without method defaults to AUTO
|
||||||
|
NOTABLE -> NOTABLE
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Unknown None
|
||||||
|
UNKNOWN(new Score(Significance.UNKNOWN, Priority.NORMAL)),
|
||||||
|
// GOOD_MEDIUM
|
||||||
|
LIKELY_NONE(new Score(Significance.LIKELY_NONE, Priority.NORMAL)),
|
||||||
|
// SUSPICIOUS_HIGH / BAD_MEDIUM
|
||||||
|
LIKELY_NOTABLE(new Score(Significance.LIKELY_NOTABLE, Priority.NORMAL)),
|
||||||
|
// GOOD_HIGH
|
||||||
|
NONE(new Score(Significance.NONE, Priority.NORMAL)),
|
||||||
|
// BAD_HIGH
|
||||||
|
NOTABLE(new Score(Significance.NOTABLE, Priority.NORMAL)),
|
||||||
|
// SUSPICIOUS (User flagged)
|
||||||
|
LIKELY_NOTABLE_MANUAL(new Score(Significance.LIKELY_NOTABLE, Priority.OVERRIDE)),
|
||||||
|
// Good (User flagged)
|
||||||
|
NONE_MANUAL(new Score(Significance.NONE, Priority.OVERRIDE)),
|
||||||
|
// Bad (User flagged)
|
||||||
|
NOTABLE_MANUAL(new Score(Significance.NOTABLE, Priority.OVERRIDE));
|
||||||
|
|
||||||
|
|
||||||
|
private final Score tskScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a CTScore instance based on score
|
||||||
|
* @param tskScore
|
||||||
|
*/
|
||||||
|
private CTScore(Score tskScore) {
|
||||||
|
|
||||||
|
checkArgument(tskScore.getSignificance() == Significance.UNKNOWN ? tskScore.getPriority() == Priority.NORMAL : true, "Unknown Conclusions expects no (NORMAL) priority");
|
||||||
|
this.tskScore = tskScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Score getTskCore() {
|
||||||
|
return tskScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("Method Category", tskScore.getPriority())
|
||||||
|
.add("Significance", tskScore.getSignificance()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POJO for after encrypted boost license has been decrypted.
|
||||||
|
*/
|
||||||
|
public class DecryptedLicenseResponse {
|
||||||
|
|
||||||
|
private final String boostLicenseId;
|
||||||
|
private final String licenseHostId;
|
||||||
|
private final ZonedDateTime expirationDate;
|
||||||
|
private final Long hashLookups;
|
||||||
|
private final Long fileUploads;
|
||||||
|
private final ZonedDateTime activationTime;
|
||||||
|
private final String product;
|
||||||
|
private final String limitType;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public DecryptedLicenseResponse(
|
||||||
|
@JsonProperty("boostLicenseId") String boostLicenseId,
|
||||||
|
@JsonProperty("licenseHostId") String licenseHostId,
|
||||||
|
@JsonProperty("expirationDate") ZonedDateTime expirationDate,
|
||||||
|
@JsonProperty("hashLookups") Long hashLookups,
|
||||||
|
@JsonProperty("fileUploads") Long fileUploads,
|
||||||
|
@JsonProperty("activationTime") ZonedDateTime activationTime,
|
||||||
|
@JsonProperty("product") String product,
|
||||||
|
@JsonProperty("limitType") String limitType
|
||||||
|
) {
|
||||||
|
this.boostLicenseId = boostLicenseId;
|
||||||
|
this.licenseHostId = licenseHostId;
|
||||||
|
this.expirationDate = expirationDate;
|
||||||
|
this.hashLookups = hashLookups;
|
||||||
|
this.fileUploads = fileUploads;
|
||||||
|
this.activationTime = activationTime;
|
||||||
|
this.product = product;
|
||||||
|
this.limitType = limitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBoostLicenseId() {
|
||||||
|
return boostLicenseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLicenseHostId() {
|
||||||
|
return licenseHostId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getHashLookups() {
|
||||||
|
return hashLookups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFileUploads() {
|
||||||
|
return fileUploads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getActivationTime() {
|
||||||
|
return activationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLimitType() {
|
||||||
|
return limitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getExpirationDate() {
|
||||||
|
return expirationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file reputation result regarding malware status.
|
||||||
|
*/
|
||||||
|
public class FileReputationResult {
|
||||||
|
|
||||||
|
public static enum Status {
|
||||||
|
FOUND,
|
||||||
|
NOT_FOUND,
|
||||||
|
ERROR,
|
||||||
|
LIMITS_EXCEEDED,
|
||||||
|
BEING_SCANNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CorrelationFrequency {
|
||||||
|
UNIQUE,
|
||||||
|
RARE,
|
||||||
|
COMMON;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String malwareDescription;
|
||||||
|
private final Status status;
|
||||||
|
private final CTScore score;
|
||||||
|
private final String md5Hash;
|
||||||
|
private final String sha1Hash;
|
||||||
|
private final ZonedDateTime firstScanDate;
|
||||||
|
private final ZonedDateTime lastScanDate;
|
||||||
|
private final List<MetadataLabel> metadata;
|
||||||
|
private final String statusDescription;
|
||||||
|
private final CorrelationFrequency frequency;
|
||||||
|
private final String frequencyDescription;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public FileReputationResult(
|
||||||
|
@JsonProperty("malwareDescription") String malwareDescription,
|
||||||
|
@JsonProperty("status") Status status,
|
||||||
|
@JsonProperty("score") CTScore score,
|
||||||
|
@JsonProperty("md5Hash") String md5Hash,
|
||||||
|
@JsonProperty("sha1Hash") String sha1Hash,
|
||||||
|
@JsonProperty("firstScanDate") ZonedDateTime firstScanDate,
|
||||||
|
@JsonProperty("lastScanDate") ZonedDateTime lastScanDate,
|
||||||
|
@JsonProperty("metadata") List<MetadataLabel> metadata,
|
||||||
|
@JsonProperty("statusDescription") String statusDescription,
|
||||||
|
@JsonProperty("frequency") CorrelationFrequency frequency,
|
||||||
|
@JsonProperty("frequencyDescription") String frequencyDescription
|
||||||
|
) {
|
||||||
|
this.malwareDescription = malwareDescription;
|
||||||
|
this.status = status;
|
||||||
|
this.score = score;
|
||||||
|
this.md5Hash = md5Hash;
|
||||||
|
this.sha1Hash = sha1Hash;
|
||||||
|
this.firstScanDate = firstScanDate;
|
||||||
|
this.lastScanDate = lastScanDate;
|
||||||
|
this.metadata = metadata;
|
||||||
|
this.statusDescription = statusDescription;
|
||||||
|
this.frequency = frequency;
|
||||||
|
this.frequencyDescription = frequencyDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMalwareDescription() {
|
||||||
|
return malwareDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CTScore getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMd5Hash() {
|
||||||
|
return md5Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSha1Hash() {
|
||||||
|
return sha1Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getFirstScanDate() {
|
||||||
|
return firstScanDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getLastScanDate() {
|
||||||
|
return lastScanDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MetadataLabel> getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatusDescription() {
|
||||||
|
return statusDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorrelationFrequency getFrequency() {
|
||||||
|
return frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFrequencyDescription() {
|
||||||
|
return frequencyDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains license info and decrypted boost license.
|
||||||
|
*/
|
||||||
|
public class LicenseInfo {
|
||||||
|
private final LicenseResponse licenseResponse;
|
||||||
|
private final DecryptedLicenseResponse decryptedLicense;
|
||||||
|
|
||||||
|
public LicenseInfo(LicenseResponse licenseResponse, DecryptedLicenseResponse decryptedLicense) {
|
||||||
|
this.licenseResponse = licenseResponse;
|
||||||
|
this.decryptedLicense = decryptedLicense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseResponse getLicenseResponse() {
|
||||||
|
return licenseResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecryptedLicenseResponse getDecryptedLicense() {
|
||||||
|
return decryptedLicense;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
public String getUser() {
|
||||||
|
return "TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
public String getEmail() {
|
||||||
|
return "TBD";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POJO for license request information.
|
||||||
|
*/
|
||||||
|
public class LicenseRequest {
|
||||||
|
@JsonProperty("host_id")
|
||||||
|
private String hostId;
|
||||||
|
|
||||||
|
@JsonProperty("boost_license_code")
|
||||||
|
private String boostLicenseCode;
|
||||||
|
|
||||||
|
@JsonProperty("product")
|
||||||
|
private String product;
|
||||||
|
|
||||||
|
public String getHostId() {
|
||||||
|
return hostId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseRequest setHostId(String hostId) {
|
||||||
|
this.hostId = hostId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBoostLicenseCode() {
|
||||||
|
return boostLicenseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseRequest setBoostLicenseCode(String boostLicenseCode) {
|
||||||
|
this.boostLicenseCode = boostLicenseCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseRequest setProduct(String product) {
|
||||||
|
this.product = product;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response POJO for request for license.
|
||||||
|
*/
|
||||||
|
public class LicenseResponse {
|
||||||
|
private final Boolean success;
|
||||||
|
private final Boolean hostChanged;
|
||||||
|
private final Long hostChangesRemaining;
|
||||||
|
private final BoostLicenseResponse boostLicense;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public LicenseResponse(
|
||||||
|
@JsonProperty("success") Boolean success,
|
||||||
|
@JsonProperty("hostChanged") Boolean hostChanged,
|
||||||
|
@JsonProperty("hostChangesRemaining") Long hostChangesRemaining,
|
||||||
|
@JsonProperty("boostLicense") BoostLicenseResponse boostLicense
|
||||||
|
) {
|
||||||
|
this.success = success;
|
||||||
|
this.hostChanged = hostChanged;
|
||||||
|
this.hostChangesRemaining = hostChangesRemaining;
|
||||||
|
this.boostLicense = boostLicense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isHostChanged() {
|
||||||
|
return hostChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getHostChangesRemaining() {
|
||||||
|
return hostChangesRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoostLicenseResponse getBoostLicense() {
|
||||||
|
return boostLicense;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.json;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author gregd
|
||||||
|
*/
|
||||||
|
public class MetadataLabel {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final String value;
|
||||||
|
private final String extendedInfo;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public MetadataLabel(
|
||||||
|
@JsonProperty("key") String key,
|
||||||
|
@JsonProperty("value") String value,
|
||||||
|
@JsonProperty("info") String extendedInfo
|
||||||
|
) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
this.extendedInfo = extendedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtendedInfo() {
|
||||||
|
return extendedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2021 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.util;
|
||||||
|
|
||||||
|
import com.license4j.HardwareID;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to generate license hostID and Target hostID for malware scan
|
||||||
|
*
|
||||||
|
* @author rishwanth
|
||||||
|
*/
|
||||||
|
public class CTHostIDGenerationUtil {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CTHostIDGenerationUtil.class.getName());
|
||||||
|
private static final String USER_NAME = System.getProperty("user.name");
|
||||||
|
private static String HOST_NAME = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host ID Algorithm: Get MAC address from License4J. Get MD5 hash of it and
|
||||||
|
* grab the first 16 characters of the hash. Get user name that Cyber Triage
|
||||||
|
* is running as. MD5 hash of user name. Grab first 16 characters.
|
||||||
|
* Concatenate them and separate with underscore. Example:
|
||||||
|
* c84f70d1baf96420_7d7519bf21602c24
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String generateLicenseHostID() {
|
||||||
|
if (StringUtils.isBlank(HOST_NAME)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
HOST_NAME = StringUtils.defaultString(InetAddress.getLocalHost().getCanonicalHostName());
|
||||||
|
} catch (UnknownHostException ex) {
|
||||||
|
LOGGER.log(Level.WARNING, "UNable to determine host name.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String macAddressMd5 = StringUtils.isNotBlank(HardwareID.getHardwareIDFromEthernetAddress()) ? Md5HashUtil.getMD5MessageDigest(HardwareID.getHardwareIDFromEthernetAddress()).substring(0, 16) : Md5HashUtil.getMD5MessageDigest(HOST_NAME).substring(0, 16);
|
||||||
|
String usernameMd5 = StringUtils.isNotBlank(USER_NAME) ? Md5HashUtil.getMD5MessageDigest(USER_NAME).substring(0, 16) : Md5HashUtil.getMD5MessageDigest(HOST_NAME).substring(0, 16);
|
||||||
|
String md5 = macAddressMd5 + "_" + usernameMd5;
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.util;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.BoostLicenseResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.DecryptedLicenseResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.KeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Base64;
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypts the payload of boost license.
|
||||||
|
*/
|
||||||
|
public class LicenseDecryptorUtil {
|
||||||
|
|
||||||
|
private static final LicenseDecryptorUtil instance = new LicenseDecryptorUtil();
|
||||||
|
|
||||||
|
public static LicenseDecryptorUtil getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = ObjectMapperUtil.getInstance().getDefaultObjectMapper();
|
||||||
|
|
||||||
|
private LicenseDecryptorUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LicenseInfo createLicenseInfo(LicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
|
||||||
|
if (licenseResponse == null || licenseResponse.getBoostLicense() == null) {
|
||||||
|
throw new InvalidLicenseException("License or boost license are null");
|
||||||
|
}
|
||||||
|
|
||||||
|
DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense());
|
||||||
|
return new LicenseInfo(licenseResponse, decrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypts a boost license response.
|
||||||
|
*
|
||||||
|
* @param licenseResponse The boost license response.
|
||||||
|
* @return The decrypted license response.
|
||||||
|
* @throws JsonProcessingException
|
||||||
|
* @throws
|
||||||
|
* com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException
|
||||||
|
*/
|
||||||
|
public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
|
||||||
|
|
||||||
|
String decryptedJsonResponse;
|
||||||
|
try {
|
||||||
|
decryptedJsonResponse = decryptLicenseString(
|
||||||
|
licenseResponse.getEncryptedJson(),
|
||||||
|
licenseResponse.getIv(),
|
||||||
|
licenseResponse.getEncryptedKey(),
|
||||||
|
licenseResponse.getVersion()
|
||||||
|
);
|
||||||
|
} catch (IOException | GeneralSecurityException ex) {
|
||||||
|
throw new InvalidLicenseException("An exception occurred while parsing the license string", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
DecryptedLicenseResponse decryptedLicense = objectMapper.readValue(decryptedJsonResponse, DecryptedLicenseResponse.class);
|
||||||
|
if (!"CYBERTRIAGE".equalsIgnoreCase(decryptedLicense.getProduct())) {
|
||||||
|
// license file is expected to contain product of "CYBERTRIAGE"
|
||||||
|
throw new InvalidLicenseException("Not a valid Cyber Triage license");
|
||||||
|
}
|
||||||
|
|
||||||
|
return decryptedLicense;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version) throws IOException, GeneralSecurityException, InvalidLicenseException {
|
||||||
|
if (!"1.0".equals(version)) {
|
||||||
|
throw new InvalidLicenseException("Unexpected file version: " + version);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] encryptedKeyBytes = Base64.getDecoder().decode(encryptedKey);
|
||||||
|
byte[] keyBytes = decryptKey(encryptedKeyBytes);
|
||||||
|
SecretKey key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");
|
||||||
|
|
||||||
|
byte[] ivBytes = Base64.getDecoder().decode(ivBase64);
|
||||||
|
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||||
|
|
||||||
|
byte[] encryptedLicenseJsonBytes = Base64.getDecoder().decode(encryptedJson);
|
||||||
|
|
||||||
|
String algorithm = "AES/CBC/PKCS5Padding";
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||||
|
byte[] licenseJsonBytes = cipher.doFinal(encryptedLicenseJsonBytes);
|
||||||
|
|
||||||
|
return new String(licenseJsonBytes, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PublicKey getPublicKey() throws InvalidKeySpecException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
|
String publicKeyString = """
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwIKulLyaLQ2WeO0gIW2G
|
||||||
|
3jQqny3Y/7VUevBKulAEywaUbvECvZ4zGsnaMyACjXxMNkA1xU2WeSMP/WqC03wz
|
||||||
|
4d71liUeAqOYKMdGHXFN2qswWz/ufK6An0pTEqYaoiUfcwSBVo2ZTUcMQexScKaS
|
||||||
|
ghmaWqBHBYx+lBkVMcLG2PtLDRZbqgJvJr2QCzMSVUpEGGQEWs7YolIq46KCgqsq
|
||||||
|
pTdfrdqd59x6oRhTLegswzxwLyouvrKbRqKR2ZRbVvlGtUnnnlLDuhEfd0flMxuv
|
||||||
|
W98Siw6dWe1K3x45nDu5py2G9Q9fZS8/2KHUC6QcLLstLIoPnZjCl9Lcur1U6s9N
|
||||||
|
f5aLI9mwMfmSJsoVOuwx2/MC98uHvPoPbG4ZjiT0aaGg4JccTGD6pssDA35zPhkk
|
||||||
|
1l6wktEYtyF2A7zjzuFxioQz8fHBzIbHPCxzu4S2gh3qOVFf7c9COmX9MsnB70o2
|
||||||
|
EZ1rxlFIJ7937IGJNwWOQuiMKTpEeT6BwTdQNZQPqCUGvZ5eEjhrm57yCF4zuyrt
|
||||||
|
AR8DG7ahK2YAarADHRyxTuxH1qY7E5/CTQKYk9tIYsV4O05CKj7B8rBMtjVNjb4b
|
||||||
|
d7JwPW43Z3J6jo/gLlVdGSPg8vQDNVLl6sdDM4Pm1eJEzgR2JlqXDCRDUGNNsXH2
|
||||||
|
qt9Ru8ykX7PAfF2Q3/qg1jkCAwEAAQ==
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
""";
|
||||||
|
|
||||||
|
publicKeyString = publicKeyString.replaceAll("-----BEGIN PUBLIC KEY-----", "").replaceAll("-----END PUBLIC KEY-----", "").replaceAll("\\s", "");
|
||||||
|
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
|
||||||
|
|
||||||
|
KeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(keySpec);
|
||||||
|
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] decryptKey(byte[] encryptedKeyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
|
||||||
|
PublicKey publicKey = getPublicKey();
|
||||||
|
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("RSA");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||||
|
|
||||||
|
byte[] decryptedBytes = decryptCipher.doFinal(encryptedKeyBytes);
|
||||||
|
|
||||||
|
return decryptedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InvalidLicenseException extends Exception {
|
||||||
|
|
||||||
|
public InvalidLicenseException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidLicenseException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2018 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.util;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.hash.HashCode;
|
||||||
|
import com.google.common.hash.HashFunction;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jayaram
|
||||||
|
*/
|
||||||
|
public class Md5HashUtil {
|
||||||
|
/**
|
||||||
|
* Returns MD5 hash value for the lower case value of the string provided.
|
||||||
|
* @param inp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getMD5MessageDigest(String inp) {
|
||||||
|
if (StringUtils.isNotBlank(inp)) {
|
||||||
|
HashFunction hf = Hashing.md5(); // Using despite its deprecation as md5 is good enough for our uses.
|
||||||
|
HashCode hc = hf.newHasher()
|
||||||
|
.putString(inp.toLowerCase(), Charsets.UTF_8)
|
||||||
|
.hash();
|
||||||
|
return hc.toString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctapi.util;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates default ObjectMapper
|
||||||
|
*/
|
||||||
|
public class ObjectMapperUtil {
|
||||||
|
|
||||||
|
private static final ObjectMapperUtil instance = new ObjectMapperUtil();
|
||||||
|
|
||||||
|
public static ObjectMapperUtil getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectMapperUtil() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectMapper getDefaultObjectMapper() {
|
||||||
|
ObjectMapper defaultMapper = new ObjectMapper();
|
||||||
|
defaultMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
defaultMapper.registerModule(new JavaTimeModule());
|
||||||
|
return defaultMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
|
||||||
|
OptionsCategory_Name_CyberTriage=CyberTriage
|
||||||
|
OptionsCategory_Keywords_CyberTriage=CyberTriage,Cyber,Triage
|
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
|
||||||
|
OptionsCategory_Name_CyberTriage=CyberTriage
|
||||||
|
OptionsCategory_Keywords_CyberTriage=CyberTriage,Cyber,Triage
|
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,120,0,0,2,2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="scrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<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"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="contentPane">
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,141 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import org.netbeans.spi.options.OptionsPanelController;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options panel for CyberTriage.
|
||||||
|
*/
|
||||||
|
public class CTOptionsPanel extends IngestModuleGlobalSettingsPanel {
|
||||||
|
private static final int MAX_SUBPANEL_WIDTH = 500;
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(CTOptionsPanel.class.getName());
|
||||||
|
|
||||||
|
private final List<CTOptionsSubPanel> subPanels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form CTOptions
|
||||||
|
*/
|
||||||
|
public CTOptionsPanel() {
|
||||||
|
initComponents();
|
||||||
|
Collection<? extends CTOptionsSubPanel> coll = Lookup.getDefault().lookupAll(CTOptionsSubPanel.class);
|
||||||
|
Stream<? extends CTOptionsSubPanel> panelStream = coll != null ? coll.stream() : Stream.empty();
|
||||||
|
this.subPanels = panelStream
|
||||||
|
.sorted(Comparator.comparing(p -> p.getClass().getSimpleName().toUpperCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
addSubOptionsPanels(this.subPanels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSubOptionsPanels(List<CTOptionsSubPanel> subPanels) {
|
||||||
|
for (int i = 0; i < subPanels.size(); i++) {
|
||||||
|
CTOptionsSubPanel subPanel = subPanels.get(i);
|
||||||
|
|
||||||
|
subPanel.addPropertyChangeListener(new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) {
|
||||||
|
CTOptionsPanel.this.firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
GridBagConstraints gridBagConstraints = new GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = i;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(i == 0 ? 5 : 0, 5, 5, 5);
|
||||||
|
gridBagConstraints.weighty = 0;
|
||||||
|
gridBagConstraints.weightx = 0;
|
||||||
|
|
||||||
|
contentPane.add(subPanel, gridBagConstraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridBagConstraints verticalConstraints = new GridBagConstraints();
|
||||||
|
verticalConstraints.gridx = 0;
|
||||||
|
verticalConstraints.gridy = subPanels.size();
|
||||||
|
verticalConstraints.weighty = 1;
|
||||||
|
verticalConstraints.weightx = 0;
|
||||||
|
|
||||||
|
JPanel verticalSpacer = new JPanel();
|
||||||
|
|
||||||
|
verticalSpacer.setMinimumSize(new Dimension(MAX_SUBPANEL_WIDTH, 0));
|
||||||
|
verticalSpacer.setPreferredSize(new Dimension(MAX_SUBPANEL_WIDTH, 0));
|
||||||
|
verticalSpacer.setMaximumSize(new Dimension(MAX_SUBPANEL_WIDTH, Short.MAX_VALUE));
|
||||||
|
contentPane.add(verticalSpacer, verticalConstraints);
|
||||||
|
|
||||||
|
|
||||||
|
GridBagConstraints horizontalConstraints = new GridBagConstraints();
|
||||||
|
horizontalConstraints.gridx = 1;
|
||||||
|
horizontalConstraints.gridy = 0;
|
||||||
|
horizontalConstraints.weighty = 0;
|
||||||
|
horizontalConstraints.weightx = 1;
|
||||||
|
|
||||||
|
JPanel horizontalSpacer = new JPanel();
|
||||||
|
contentPane.add(horizontalSpacer, horizontalConstraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.JScrollPane scrollPane = new javax.swing.JScrollPane();
|
||||||
|
contentPane = new javax.swing.JPanel();
|
||||||
|
|
||||||
|
setLayout(new java.awt.BorderLayout());
|
||||||
|
|
||||||
|
contentPane.setLayout(new java.awt.GridBagLayout());
|
||||||
|
scrollPane.setViewportView(contentPane);
|
||||||
|
|
||||||
|
add(scrollPane, java.awt.BorderLayout.CENTER);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveSettings() {
|
||||||
|
subPanels.forEach(panel -> panel.saveSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadSavedSettings() {
|
||||||
|
subPanels.forEach(panel -> panel.loadSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean valid() {
|
||||||
|
return subPanels.stream().allMatch(panel -> panel.valid());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JPanel contentPane;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import org.netbeans.spi.options.OptionsPanelController;
|
||||||
|
import org.openide.util.HelpCtx;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options panel controller for CyberTriage.
|
||||||
|
*/
|
||||||
|
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_CyberTriage",
|
||||||
|
iconBase = "com/basistech/df/cybertriage/autopsy/images/logo.png",
|
||||||
|
position = 999999,
|
||||||
|
keywords = "#OptionsCategory_Keywords_CyberTriage",
|
||||||
|
keywordsCategory = "CyberTriage")
|
||||||
|
public final class CTOptionsPanelController extends OptionsPanelController {
|
||||||
|
|
||||||
|
private CTOptionsPanel panel;
|
||||||
|
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
|
private boolean changed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component should load its data here.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
getPanel().loadSavedSettings();
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when both the Ok and Apply buttons are pressed. It
|
||||||
|
* applies to any of the panels that have been opened in the process of
|
||||||
|
* using the options pane.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void applyChanges() {
|
||||||
|
if (changed) {
|
||||||
|
getPanel().saveSettings();
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when the Cancel button is pressed. It applies to
|
||||||
|
* any of the panels that have been opened in the process of using the
|
||||||
|
* options pane.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
return getPanel().valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine whether any changes have been made to this controller's
|
||||||
|
* panel.
|
||||||
|
*
|
||||||
|
* @return Whether or not a change has been made.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isChanged() {
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HelpCtx getHelpCtx() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent(Lookup masterLookup) {
|
||||||
|
return getPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||||
|
pcs.addPropertyChangeListener(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||||
|
pcs.removePropertyChangeListener(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CTOptionsPanel getPanel() {
|
||||||
|
if (panel == null) {
|
||||||
|
panel = new CTOptionsPanel();
|
||||||
|
panel.addPropertyChangeListener(new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) {
|
||||||
|
changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void changed() {
|
||||||
|
if (!changed) {
|
||||||
|
changed = true;
|
||||||
|
pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
|
||||||
|
}
|
||||||
|
pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
|
||||||
|
|
||||||
|
|
||||||
|
CTLicenseDialog.licenseNumberLabel.text=License Number:
|
||||||
|
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||||
|
CTLicenseDialog.cancelButton.text=Cancel
|
||||||
|
CTLicenseDialog.okButton.text=Ok
|
||||||
|
CTLicenseDialog.warningLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.countersResetLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title=License Info
|
||||||
|
CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scans
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoAddButton.text=Add License
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text=
|
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
|
||||||
|
|
||||||
|
|
||||||
|
CTLicenseDialog.licenseNumberLabel.text=License Number:
|
||||||
|
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||||
|
CTLicenseDialog.cancelButton.text=Cancel
|
||||||
|
CTLicenseDialog.okButton.text=Ok
|
||||||
|
CTLicenseDialog.warningLabel.text=
|
||||||
|
CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html>
|
||||||
|
CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.countersResetLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title=License Info
|
||||||
|
CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scans
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoAddButton.text=Add License
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text=
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialog_desc=License Number:
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialog_title=Add a License...
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_desc=The license number has already been entered
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_title=License Number Already Entered
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_desc=Please verify that license number is of format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
||||||
|
CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_title=Invalid License Number
|
||||||
|
CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error
|
||||||
|
CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.
|
||||||
|
CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error
|
||||||
|
# {0} - expiresDate
|
||||||
|
CTMalwareScannerOptionsPanel_licenseInfo_expires=Expires: {0}
|
||||||
|
# {0} - idNumber
|
||||||
|
CTMalwareScannerOptionsPanel_licenseInfo_id=ID: {0}
|
||||||
|
# {0} - userName
|
||||||
|
# {1} - email
|
||||||
|
CTMalwareScannerOptionsPanel_licenseInfo_userInfo=<html>User: {0}<br/>Email: {1}</html>
|
||||||
|
# {0} - countersResetDate
|
||||||
|
CTMalwareScannerOptionsPanel_malwareScans_countersReset=Counters reset: {0}
|
||||||
|
# {0} - fileUploadsRemaining
|
||||||
|
CTMalwareScannerOptionsPanel_malwareScans_fileUploadsRemaining=File uploads remaining: {0}
|
||||||
|
# {0} - hashLookupsRemaining
|
||||||
|
CTMalwareScannerOptionsPanel_malwareScans_hashLookupsRemaining=Hash lookups remaining: {0}
|
||||||
|
# {0} - maxDailyFileLookups
|
||||||
|
CTMalwareScannerOptionsPanel_malwareScans_maxDailyFileLookups=Max file uploads: {0}/day
|
||||||
|
# {0} - maxDailyLookups
|
||||||
|
CTMalwareScannerOptionsPanel_malwareScans_maxDailyHashLookups=Max Hash lookups: {0}/day
|
||||||
|
CTMalwareScannerOptionsPanel_MalwareScansFetcher_apiErr_title=Server Error
|
||||||
|
CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_desc=A general error occurred while fetching malware scans information. Please try again later.
|
||||||
|
CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_title=General Error
|
||||||
|
CTOPtionsPanel_loadLicenseInfo_loading=Loading...
|
||||||
|
CTOPtionsPanel_loadMalwareScansInfo_loading=Loading...
|
@ -0,0 +1,138 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||||
|
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/Bundle.properties" key="CTLicenseDialog.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="alwaysOnTop" type="boolean" value="true"/>
|
||||||
|
<Property name="resizable" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<SyntheticProperties>
|
||||||
|
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||||
|
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||||
|
</SyntheticProperties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,122,0,0,1,-19"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="licenseNumberLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.licenseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="warningLabel">
|
||||||
|
<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="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[419, 36]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[419, 36]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[419, 36]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="buttonPadding">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JButton" name="okButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="2" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="cancelButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="licenseNumberTextField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.licenseNumberTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,192 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* License dialog
|
||||||
|
*/
|
||||||
|
public class CTLicenseDialog extends javax.swing.JDialog {
|
||||||
|
|
||||||
|
private static final Pattern LICENSE_PATTERN = Pattern.compile("^\\s*[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}\\s*$");
|
||||||
|
|
||||||
|
private String licenseString = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form CTLicenseDialog
|
||||||
|
*/
|
||||||
|
public CTLicenseDialog(java.awt.Frame parent, boolean modal) {
|
||||||
|
super(parent, modal);
|
||||||
|
initComponents();
|
||||||
|
this.licenseNumberTextField.getDocument().putProperty("filterNewlines", Boolean.TRUE);
|
||||||
|
this.licenseNumberTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
@Override
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
verifyInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
verifyInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
verifyInput();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String getValue() {
|
||||||
|
return licenseString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html>"
|
||||||
|
})
|
||||||
|
private void verifyInput() {
|
||||||
|
String licenseInput = StringUtils.defaultString(this.licenseNumberTextField.getText());
|
||||||
|
if (LICENSE_PATTERN.matcher(licenseInput).matches()) {
|
||||||
|
this.warningLabel.setText("");
|
||||||
|
this.okButton.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
this.warningLabel.setText(Bundle.CTLicenseDialog_verifyInput_licenseNumberError());
|
||||||
|
this.okButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
javax.swing.JLabel licenseNumberLabel = new javax.swing.JLabel();
|
||||||
|
warningLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.JPanel buttonPadding = new javax.swing.JPanel();
|
||||||
|
okButton = new javax.swing.JButton();
|
||||||
|
cancelButton = new javax.swing.JButton();
|
||||||
|
licenseNumberTextField = new javax.swing.JTextField();
|
||||||
|
|
||||||
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
setTitle(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.title")); // NOI18N
|
||||||
|
setAlwaysOnTop(true);
|
||||||
|
setResizable(false);
|
||||||
|
getContentPane().setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseNumberLabel, org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
getContentPane().add(licenseNumberLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
warningLabel.setForeground(java.awt.Color.RED);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.warningLabel.text")); // NOI18N
|
||||||
|
warningLabel.setMaximumSize(new java.awt.Dimension(419, 36));
|
||||||
|
warningLabel.setMinimumSize(new java.awt.Dimension(419, 36));
|
||||||
|
warningLabel.setPreferredSize(new java.awt.Dimension(419, 36));
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
getContentPane().add(warningLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout buttonPaddingLayout = new javax.swing.GroupLayout(buttonPadding);
|
||||||
|
buttonPadding.setLayout(buttonPaddingLayout);
|
||||||
|
buttonPaddingLayout.setHorizontalGroup(
|
||||||
|
buttonPaddingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
buttonPaddingLayout.setVerticalGroup(
|
||||||
|
buttonPaddingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
getContentPane().add(buttonPadding, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.okButton.text")); // NOI18N
|
||||||
|
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
okButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 2;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
getContentPane().add(okButton, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.cancelButton.text")); // NOI18N
|
||||||
|
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
cancelButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
getContentPane().add(cancelButton, gridBagConstraints);
|
||||||
|
|
||||||
|
licenseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
getContentPane().add(licenseNumberTextField, gridBagConstraints);
|
||||||
|
|
||||||
|
pack();
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||||
|
this.licenseString = this.licenseNumberTextField.getText();
|
||||||
|
this.dispose();
|
||||||
|
}//GEN-LAST:event_okButtonActionPerformed
|
||||||
|
|
||||||
|
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||||
|
this.licenseString = null;
|
||||||
|
this.dispose();
|
||||||
|
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JButton cancelButton;
|
||||||
|
private javax.swing.JTextField licenseNumberTextField;
|
||||||
|
private javax.swing.JButton okButton;
|
||||||
|
private javax.swing.JLabel warningLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.util.ObjectMapperUtil;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles persisting CT Settings.
|
||||||
|
*/
|
||||||
|
public class CTLicensePersistence {
|
||||||
|
|
||||||
|
private static final String CT_SETTINGS_DIR = "CyberTriage";
|
||||||
|
private static final String CT_LICENSE_FILENAME = "CyberTriageLicense.json";
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(CTLicensePersistence.class.getName());
|
||||||
|
|
||||||
|
private static final CTLicensePersistence instance = new CTLicensePersistence();
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = ObjectMapperUtil.getInstance().getDefaultObjectMapper();
|
||||||
|
|
||||||
|
public static CTLicensePersistence getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean saveLicenseResponse(LicenseResponse licenseResponse) {
|
||||||
|
if (licenseResponse != null) {
|
||||||
|
File licenseFile = getCTLicenseFile();
|
||||||
|
try {
|
||||||
|
objectMapper.writeValue(licenseFile, licenseResponse);
|
||||||
|
return true;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "There was an error writing CyberTriage license to file: " + licenseFile.getAbsolutePath(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Optional<LicenseResponse> loadLicenseResponse() {
|
||||||
|
Optional<LicenseResponse> toRet = Optional.empty();
|
||||||
|
File licenseFile = getCTLicenseFile();
|
||||||
|
if (licenseFile.isFile()) {
|
||||||
|
try {
|
||||||
|
toRet = Optional.ofNullable(objectMapper.readValue(licenseFile, LicenseResponse.class));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "There was an error reading CyberTriage license to file: " + licenseFile.getAbsolutePath(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return toRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Optional<LicenseInfo> loadLicenseInfo() {
|
||||||
|
return loadLicenseResponse().flatMap((license) -> {
|
||||||
|
try {
|
||||||
|
return Optional.ofNullable(LicenseDecryptorUtil.getInstance().createLicenseInfo(license));
|
||||||
|
} catch (JsonProcessingException | LicenseDecryptorUtil.InvalidLicenseException ex) {
|
||||||
|
logger.log(Level.WARNING, "There was an error decrypting license data from license file", ex);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getCTLicenseFile() {
|
||||||
|
return Paths.get(PlatformUtil.getModuleConfigDirectory(), CT_SETTINGS_DIR, CT_LICENSE_FILENAME).toFile();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-109,0,0,1,-29"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="licenseInfoPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
|
<TitledBorder title="License Info">
|
||||||
|
<ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</TitledBorder>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="licenseInfoMessageLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="licenseInfoUserLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="licenseInfoExpiresLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="licenseInfoIdLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="licenseInfoAddButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoAddButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="licenseInfoAddButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="12" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="malwareScansPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
|
<TitledBorder title="Malware Scans">
|
||||||
|
<ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.malwareScansPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</TitledBorder>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="malwareScansMessageLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="maxHashLookupsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="maxFileUploadsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="countersResetLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.countersResetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="hashLookupsRemainingLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="fileUploadsRemainingLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,551 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.CTCloudException;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.CtApiDAO;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthTokenResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.openide.windows.WindowManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options panel for CyberTriage options for importing a CyberTriage incident
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = CTOptionsSubPanel.class)
|
||||||
|
public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(CTMalwareScannerOptionsPanel.class.getName());
|
||||||
|
|
||||||
|
private static final SimpleDateFormat LICENSE_EXPIRES_FORMAT = new SimpleDateFormat("MMMM d, YYYY");
|
||||||
|
private static final SimpleDateFormat MALWARE_SCANS_RESET_FORMAT = new SimpleDateFormat("MMM d, YYYY' at 'h:mma");
|
||||||
|
|
||||||
|
private final CtApiDAO ctApiDAO = CtApiDAO.getInstance();
|
||||||
|
private final CTLicensePersistence ctPersistence = CTLicensePersistence.getInstance();
|
||||||
|
|
||||||
|
private volatile LicenseInfo licenseInfo = null;
|
||||||
|
private volatile String licenseInfoMessage = null;
|
||||||
|
private volatile LicenseFetcher licenseFetcher = null;
|
||||||
|
|
||||||
|
private volatile AuthTokenResponse authTokenResponse = null;
|
||||||
|
private volatile String authTokenMessage = null;
|
||||||
|
private volatile AuthTokenFetcher authTokenFetcher = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form CTIncidentImportOptionsPanel
|
||||||
|
*/
|
||||||
|
public CTMalwareScannerOptionsPanel() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
this.addComponentListener(new ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentHidden(ComponentEvent e) {
|
||||||
|
synchronized (CTMalwareScannerOptionsPanel.this) {
|
||||||
|
if (CTMalwareScannerOptionsPanel.this.isLicenseAddRunning()) {
|
||||||
|
CTMalwareScannerOptionsPanel.this.licenseFetcher.cancel(true);
|
||||||
|
CTMalwareScannerOptionsPanel.this.licenseFetcher = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CTMalwareScannerOptionsPanel.this.isMalwareScansRunning()) {
|
||||||
|
CTMalwareScannerOptionsPanel.this.authTokenFetcher.cancel(true);
|
||||||
|
CTMalwareScannerOptionsPanel.this.authTokenFetcher = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentShown(ComponentEvent e) {
|
||||||
|
synchronized (CTMalwareScannerOptionsPanel.this) {
|
||||||
|
if (CTMalwareScannerOptionsPanel.this.licenseInfo != null) {
|
||||||
|
loadMalwareScansInfo(CTMalwareScannerOptionsPanel.this.licenseInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void saveSettings() {
|
||||||
|
ctPersistence.saveLicenseResponse(getLicenseInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean valid() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void loadSettings() {
|
||||||
|
Optional<LicenseInfo> licenseInfoOpt = ctPersistence.loadLicenseInfo();
|
||||||
|
LicenseInfo licenseInfo = licenseInfoOpt.orElse(null);
|
||||||
|
setLicenseDisplay(licenseInfo, null);
|
||||||
|
setMalwareScansDisplay(null, null);
|
||||||
|
if (licenseInfo != null) {
|
||||||
|
loadMalwareScansInfo(licenseInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized LicenseResponse getLicenseInfo() {
|
||||||
|
return this.licenseInfo == null ? null : this.licenseInfo.getLicenseResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setLicenseDisplay(LicenseInfo licenseInfo, String licenseMessage) {
|
||||||
|
this.licenseInfo = licenseInfo;
|
||||||
|
this.licenseInfoMessage = licenseMessage;
|
||||||
|
renderLicenseState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setMalwareScansDisplay(AuthTokenResponse authTokenResponse, String authTokenMessage) {
|
||||||
|
this.authTokenResponse = authTokenResponse;
|
||||||
|
this.authTokenMessage = authTokenMessage;
|
||||||
|
renderLicenseState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if there is an operation to fetch the license.
|
||||||
|
*/
|
||||||
|
private synchronized boolean isLicenseAddRunning() {
|
||||||
|
return this.licenseFetcher != null && !this.licenseFetcher.isCancelled() && !this.licenseFetcher.isDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if there is an operation to fetch malware scans information.
|
||||||
|
*/
|
||||||
|
private synchronized boolean isMalwareScansRunning() {
|
||||||
|
return this.authTokenFetcher != null && !this.authTokenFetcher.isCancelled() && !this.authTokenFetcher.isDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"CTOPtionsPanel_loadLicenseInfo_loading=Loading..."
|
||||||
|
})
|
||||||
|
private synchronized void loadLicenseInfo(String licenseNumber) {
|
||||||
|
if (isLicenseAddRunning()) {
|
||||||
|
this.licenseFetcher.cancel(true);
|
||||||
|
}
|
||||||
|
setLicenseDisplay(null, Bundle.CTOPtionsPanel_loadLicenseInfo_loading());
|
||||||
|
this.licenseFetcher = new LicenseFetcher(licenseNumber);
|
||||||
|
this.licenseFetcher.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"CTOPtionsPanel_loadMalwareScansInfo_loading=Loading..."
|
||||||
|
})
|
||||||
|
private synchronized void loadMalwareScansInfo(LicenseInfo licenseInfo) {
|
||||||
|
if (isMalwareScansRunning()) {
|
||||||
|
this.authTokenFetcher.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
setMalwareScansDisplay(null, Bundle.CTOPtionsPanel_loadMalwareScansInfo_loading());
|
||||||
|
|
||||||
|
if (licenseInfo == null || licenseInfo.getDecryptedLicense() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.authTokenFetcher = new AuthTokenFetcher(licenseInfo.getDecryptedLicense().getBoostLicenseId());
|
||||||
|
this.authTokenFetcher.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
javax.swing.JPanel licenseInfoPanel = new javax.swing.JPanel();
|
||||||
|
licenseInfoMessageLabel = new javax.swing.JLabel();
|
||||||
|
licenseInfoUserLabel = new javax.swing.JLabel();
|
||||||
|
licenseInfoExpiresLabel = new javax.swing.JLabel();
|
||||||
|
licenseInfoIdLabel = new javax.swing.JLabel();
|
||||||
|
licenseInfoAddButton = new javax.swing.JButton();
|
||||||
|
malwareScansPanel = new javax.swing.JPanel();
|
||||||
|
malwareScansMessageLabel = new javax.swing.JLabel();
|
||||||
|
maxHashLookupsLabel = new javax.swing.JLabel();
|
||||||
|
maxFileUploadsLabel = new javax.swing.JLabel();
|
||||||
|
countersResetLabel = new javax.swing.JLabel();
|
||||||
|
hashLookupsRemainingLabel = new javax.swing.JLabel();
|
||||||
|
fileUploadsRemainingLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
licenseInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title"))); // NOI18N
|
||||||
|
licenseInfoPanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseInfoMessageLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.gridwidth = 2;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
licenseInfoPanel.add(licenseInfoMessageLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseInfoUserLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
licenseInfoPanel.add(licenseInfoUserLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseInfoExpiresLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
licenseInfoPanel.add(licenseInfoExpiresLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseInfoIdLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
licenseInfoPanel.add(licenseInfoIdLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(licenseInfoAddButton, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoAddButton.text")); // NOI18N
|
||||||
|
licenseInfoAddButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
licenseInfoAddButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
licenseInfoPanel.add(licenseInfoAddButton, gridBagConstraints);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
add(licenseInfoPanel, gridBagConstraints);
|
||||||
|
|
||||||
|
malwareScansPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansPanel.border.title"))); // NOI18N
|
||||||
|
malwareScansPanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(malwareScansMessageLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.gridwidth = 2;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(malwareScansMessageLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(maxHashLookupsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(maxHashLookupsLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(maxFileUploadsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(maxFileUploadsLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(countersResetLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.countersResetLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(countersResetLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(hashLookupsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(hashLookupsRemainingLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(fileUploadsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
malwareScansPanel.add(fileUploadsRemainingLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
add(malwareScansPanel, gridBagConstraints);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialog_title=Add a License...",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialog_desc=License Number:",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_title=License Number Already Entered",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_desc=The license number has already been entered",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_title=Invalid License Number",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_desc=Please verify that license number is of format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'"})
|
||||||
|
private void licenseInfoAddButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_licenseInfoAddButtonActionPerformed
|
||||||
|
CTLicenseDialog licenseDialog = new CTLicenseDialog(WindowManager.getDefault().getMainWindow(), true);
|
||||||
|
licenseDialog.setLocationRelativeTo(this);
|
||||||
|
licenseDialog.setVisible(true);
|
||||||
|
String licenseNumber = licenseDialog.getValue();
|
||||||
|
if (licenseNumber != null) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (this.licenseInfo == null || !licenseNumber.trim().equalsIgnoreCase(this.licenseInfo.getDecryptedLicense().getBoostLicenseId())) {
|
||||||
|
loadLicenseInfo(licenseNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
this,
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_desc(),
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_title(),
|
||||||
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_licenseInfoAddButtonActionPerformed
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"# {0} - userName",
|
||||||
|
"# {1} - email",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseInfo_userInfo=<html>User: {0}<br/>Email: {1}</html>",
|
||||||
|
"# {0} - expiresDate",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseInfo_expires=Expires: {0}",
|
||||||
|
"# {0} - idNumber",
|
||||||
|
"CTMalwareScannerOptionsPanel_licenseInfo_id=ID: {0}",
|
||||||
|
"# {0} - maxDailyLookups",
|
||||||
|
"CTMalwareScannerOptionsPanel_malwareScans_maxDailyHashLookups=Max Hash lookups: {0}/day",
|
||||||
|
"# {0} - maxDailyFileLookups",
|
||||||
|
"CTMalwareScannerOptionsPanel_malwareScans_maxDailyFileLookups=Max file uploads: {0}/day",
|
||||||
|
"# {0} - countersResetDate",
|
||||||
|
"CTMalwareScannerOptionsPanel_malwareScans_countersReset=Counters reset: {0}",
|
||||||
|
"# {0} - hashLookupsRemaining",
|
||||||
|
"CTMalwareScannerOptionsPanel_malwareScans_hashLookupsRemaining=Hash lookups remaining: {0}",
|
||||||
|
"# {0} - fileUploadsRemaining",
|
||||||
|
"CTMalwareScannerOptionsPanel_malwareScans_fileUploadsRemaining=File uploads remaining: {0}"})
|
||||||
|
private synchronized void renderLicenseState() {
|
||||||
|
this.licenseInfoAddButton.setEnabled(!isLicenseAddRunning());
|
||||||
|
|
||||||
|
this.licenseInfoMessageLabel.setVisible(StringUtils.isNotBlank(this.licenseInfoMessage));
|
||||||
|
this.licenseInfoMessageLabel.setText(this.licenseInfoMessage);
|
||||||
|
|
||||||
|
if (licenseInfo == null) {
|
||||||
|
this.licenseInfoExpiresLabel.setVisible(false);
|
||||||
|
this.licenseInfoIdLabel.setVisible(false);
|
||||||
|
this.licenseInfoUserLabel.setVisible(false);
|
||||||
|
} else {
|
||||||
|
this.licenseInfoExpiresLabel.setVisible(true);
|
||||||
|
this.licenseInfoExpiresLabel.setText(Bundle.CTMalwareScannerOptionsPanel_licenseInfo_expires(LICENSE_EXPIRES_FORMAT.format(this.licenseInfo.getDecryptedLicense().getExpirationDate())));
|
||||||
|
this.licenseInfoIdLabel.setVisible(true);
|
||||||
|
this.licenseInfoIdLabel.setText(Bundle.CTMalwareScannerOptionsPanel_licenseInfo_id(this.licenseInfo.getDecryptedLicense().getBoostLicenseId()));
|
||||||
|
this.licenseInfoUserLabel.setVisible(true);
|
||||||
|
this.licenseInfoUserLabel.setText(Bundle.CTMalwareScannerOptionsPanel_licenseInfo_userInfo(this.licenseInfo.getUser(), this.licenseInfo.getEmail()));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.malwareScansPanel.setVisible(StringUtils.isNotBlank(this.authTokenMessage) || authTokenResponse != null);
|
||||||
|
|
||||||
|
this.malwareScansMessageLabel.setVisible(StringUtils.isNotBlank(this.authTokenMessage));
|
||||||
|
this.malwareScansMessageLabel.setText(this.authTokenMessage);
|
||||||
|
|
||||||
|
if (authTokenResponse == null) {
|
||||||
|
this.maxHashLookupsLabel.setVisible(false);
|
||||||
|
this.maxFileUploadsLabel.setVisible(false);
|
||||||
|
this.countersResetLabel.setVisible(false);
|
||||||
|
this.hashLookupsRemainingLabel.setVisible(false);
|
||||||
|
this.fileUploadsRemainingLabel.setVisible(false);
|
||||||
|
} else {
|
||||||
|
this.maxHashLookupsLabel.setVisible(true);
|
||||||
|
this.maxHashLookupsLabel.setText(Bundle.CTMalwareScannerOptionsPanel_malwareScans_maxDailyHashLookups(this.authTokenResponse.getHashLookupLimit()));
|
||||||
|
this.maxFileUploadsLabel.setVisible(true);
|
||||||
|
this.maxFileUploadsLabel.setText(Bundle.CTMalwareScannerOptionsPanel_malwareScans_maxDailyFileLookups(this.authTokenResponse.getFileUploadLimit()));
|
||||||
|
this.countersResetLabel.setVisible(true);
|
||||||
|
this.countersResetLabel.setText(Bundle.CTMalwareScannerOptionsPanel_malwareScans_countersReset(MALWARE_SCANS_RESET_FORMAT.format(this.authTokenResponse.getExpiration())));
|
||||||
|
this.hashLookupsRemainingLabel.setVisible(true);
|
||||||
|
this.hashLookupsRemainingLabel.setText(Bundle.CTMalwareScannerOptionsPanel_malwareScans_hashLookupsRemaining(remaining(this.authTokenResponse.getHashLookupLimit(), this.authTokenResponse.getHashLookupCount())));
|
||||||
|
this.fileUploadsRemainingLabel.setVisible(true);
|
||||||
|
this.fileUploadsRemainingLabel.setText(Bundle.CTMalwareScannerOptionsPanel_malwareScans_fileUploadsRemaining(remaining(this.authTokenResponse.getFileUploadLimit(), this.authTokenResponse.getFileUploadCount())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long remaining(Long total, Long used) {
|
||||||
|
total = total == null ? 0 : total;
|
||||||
|
used = used == null ? 0 : used;
|
||||||
|
return total - used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error",
|
||||||
|
"CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error",
|
||||||
|
"CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.",})
|
||||||
|
private class LicenseFetcher extends SwingWorker<LicenseInfo, Void> {
|
||||||
|
|
||||||
|
private final String licenseText;
|
||||||
|
|
||||||
|
public LicenseFetcher(String licenseText) {
|
||||||
|
this.licenseText = licenseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LicenseInfo doInBackground() throws Exception {
|
||||||
|
LicenseResponse licenseResponse = ctApiDAO.getLicenseInfo(licenseText);
|
||||||
|
ctPersistence.saveLicenseResponse(licenseResponse);
|
||||||
|
return LicenseDecryptorUtil.getInstance().createLicenseInfo(licenseResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
LicenseInfo licenseInfo = null;
|
||||||
|
try {
|
||||||
|
licenseInfo = get();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
// ignore cancellation
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
if (ex.getCause() != null && ex.getCause() instanceof CTCloudException cloudEx) {
|
||||||
|
logger.log(Level.WARNING, "An API error occurred while fetching license information", cloudEx);
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
CTMalwareScannerOptionsPanel.this,
|
||||||
|
cloudEx.getErrorCode().getDescription(),
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "An error occurred while fetching data", ex);
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
CTMalwareScannerOptionsPanel.this,
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc(),
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
synchronized (CTMalwareScannerOptionsPanel.this) {
|
||||||
|
CTMalwareScannerOptionsPanel.this.licenseFetcher = null;
|
||||||
|
if (!this.isCancelled()) {
|
||||||
|
setLicenseDisplay(licenseInfo, null);
|
||||||
|
loadMalwareScansInfo(licenseInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"CTMalwareScannerOptionsPanel_MalwareScansFetcher_apiErr_title=Server Error",
|
||||||
|
"CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_title=General Error",
|
||||||
|
"CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_desc=A general error occurred while fetching malware scans information. Please try again later.",})
|
||||||
|
private class AuthTokenFetcher extends SwingWorker<AuthTokenResponse, Void> {
|
||||||
|
|
||||||
|
private final String boostLicenseId;
|
||||||
|
|
||||||
|
public AuthTokenFetcher(String boostLicenseId) {
|
||||||
|
this.boostLicenseId = boostLicenseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AuthTokenResponse doInBackground() throws Exception {
|
||||||
|
return ctApiDAO.getAuthToken(boostLicenseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
AuthTokenResponse authTokenResponse = null;
|
||||||
|
try {
|
||||||
|
authTokenResponse = get();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
// ignore cancellation
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
if (ex.getCause() != null && ex.getCause() instanceof CTCloudException cloudEx) {
|
||||||
|
logger.log(Level.WARNING, "An API error occurred while fetching malware scans information for license", cloudEx);
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
CTMalwareScannerOptionsPanel.this,
|
||||||
|
cloudEx.getErrorDetails(),
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_MalwareScansFetcher_apiErr_title(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "An error occurred while fetching data", ex);
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
CTMalwareScannerOptionsPanel.this,
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_desc(),
|
||||||
|
Bundle.CTMalwareScannerOptionsPanel_MalwareScansFetcher_localErr_title(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
synchronized (CTMalwareScannerOptionsPanel.this) {
|
||||||
|
CTMalwareScannerOptionsPanel.this.authTokenFetcher = null;
|
||||||
|
if (!this.isCancelled()) {
|
||||||
|
setMalwareScansDisplay(authTokenResponse, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JLabel countersResetLabel;
|
||||||
|
private javax.swing.JLabel fileUploadsRemainingLabel;
|
||||||
|
private javax.swing.JLabel hashLookupsRemainingLabel;
|
||||||
|
private javax.swing.JButton licenseInfoAddButton;
|
||||||
|
private javax.swing.JLabel licenseInfoExpiresLabel;
|
||||||
|
private javax.swing.JLabel licenseInfoIdLabel;
|
||||||
|
private javax.swing.JLabel licenseInfoMessageLabel;
|
||||||
|
private javax.swing.JLabel licenseInfoUserLabel;
|
||||||
|
private javax.swing.JLabel malwareScansMessageLabel;
|
||||||
|
private javax.swing.JPanel malwareScansPanel;
|
||||||
|
private javax.swing.JLabel maxFileUploadsLabel;
|
||||||
|
private javax.swing.JLabel maxHashLookupsLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.ctoptions.subpanel;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A panel to be put in the CyberTriage options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class CTOptionsSubPanel extends JPanel {
|
||||||
|
public abstract void loadSettings();
|
||||||
|
public abstract void saveSettings();
|
||||||
|
public abstract boolean valid();
|
||||||
|
}
|
BIN
Core/src/com/basistech/df/cybertriage/autopsy/images/logo.png
Normal file
BIN
Core/src/com/basistech/df/cybertriage/autopsy/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,88 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.malwarescan;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a batch when number of items reaches batchSize or flush. Processing
|
||||||
|
* blocks (and subsequently add and flush operations) until previous batch
|
||||||
|
* finishes.
|
||||||
|
*/
|
||||||
|
public class BatchProcessor<T> {
|
||||||
|
|
||||||
|
private final ExecutorService processingExecutorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
private final BlockingQueue<T> batchingQueue;
|
||||||
|
private final List<T> processingQueue;
|
||||||
|
private final int batchSize;
|
||||||
|
private final Consumer<List<T>> itemsConsumer;
|
||||||
|
private final long millisTimeout;
|
||||||
|
|
||||||
|
private Future<?> lastProcessingFuture = CompletableFuture.runAsync(() -> {
|
||||||
|
});
|
||||||
|
|
||||||
|
public BatchProcessor(int batchSize, long millisTimeout, Consumer<List<T>> itemsConsumer) {
|
||||||
|
this.batchingQueue = new LinkedBlockingQueue<>(batchSize);
|
||||||
|
this.processingQueue = new ArrayList<>(batchSize);
|
||||||
|
this.batchSize = batchSize;
|
||||||
|
this.itemsConsumer = itemsConsumer;
|
||||||
|
this.millisTimeout = millisTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void clearCurrentBatch() {
|
||||||
|
batchingQueue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flush(boolean blockUntilFinished) throws InterruptedException {
|
||||||
|
asyncProcessBatch();
|
||||||
|
if (blockUntilFinished) {
|
||||||
|
lastProcessingFuture.wait(millisTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void add(T item) throws InterruptedException {
|
||||||
|
batchingQueue.add(item);
|
||||||
|
if (batchingQueue.size() >= batchSize) {
|
||||||
|
asyncProcessBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void asyncProcessBatch() throws InterruptedException {
|
||||||
|
if (!batchingQueue.isEmpty()) {
|
||||||
|
// wait for previous processing to finish
|
||||||
|
lastProcessingFuture.wait(millisTimeout);
|
||||||
|
|
||||||
|
// if 'andThen' doesn't run, clear the processing queue
|
||||||
|
processingQueue.clear();
|
||||||
|
|
||||||
|
// transfer batching queue to processing queue
|
||||||
|
batchingQueue.drainTo(processingQueue);
|
||||||
|
|
||||||
|
// submit to processor and then clear processing queue
|
||||||
|
lastProcessingFuture = processingExecutorService.submit(
|
||||||
|
() -> itemsConsumer.andThen(processingQueue -> processingQueue.clear()).accept(processingQueue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
MalwareScanIngestModule_malwareTypeDisplayName=Malware
|
||||||
|
# {0} - errorResponse
|
||||||
|
MalwareScanIngestModule_SharedProcessing_authTokenResponseError_desc=Received error: ''{0}'' when fetching the API authentication token for the license
|
||||||
|
MalwareScanIngestModule_SharedProcessing_authTokenResponseError_title=Authentication API error
|
||||||
|
MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No=NO
|
||||||
|
MalwareScanIngestModule_SharedProcessing_createAnalysisResult_Yes=YES
|
||||||
|
MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc=The remaining hash lookups for this license have been exhausted
|
||||||
|
MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title=Hash Lookups Exhausted
|
||||||
|
MalwareScanIngestModule_SharedProcessing_flushTimeout_desc=A timeout occurred while finishing processing
|
||||||
|
MalwareScanIngestModule_SharedProcessing_flushTimeout_title=Processing Timeout
|
||||||
|
MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc=An error occurred while processing hash lookup results
|
||||||
|
MalwareScanIngestModule_SharedProcessing_generalProcessingError_title=Hash Lookup Error
|
||||||
|
# {0} - errorResponse
|
||||||
|
MalwareScanIngestModule_SharedProcessing_repServicenResponseError_desc=Received error: ''{0}'' when fetching hash lookup results
|
||||||
|
MalwareScanIngestModule_SharedProcessing_repServicenResponseError_title=Lookup API error
|
||||||
|
MalwareScanIngestModule_ShareProcessing_batchTimeout_desc=Batch processing timed out
|
||||||
|
MalwareScanIngestModule_ShareProcessing_batchTimeout_title=Batch Processing Timeout
|
||||||
|
# {0} - remainingLookups
|
||||||
|
MalwareScanIngestModule_ShareProcessing_lowLimitWarning_desc=This license only has {0} lookups remaining
|
||||||
|
MalwareScanIngestModule_ShareProcessing_lowLimitWarning_title=Hash Lookups Low
|
||||||
|
MalwareScanIngestModuleFactory_description=The malware scan ingest module queries the CyberTriage cloud API for any possible malicious executables.
|
||||||
|
MalwareScanIngestModuleFactory_displayName=Malware Scan
|
||||||
|
MalwareScanIngestModuleFactory_version=1.0.0
|
@ -0,0 +1,395 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.malwarescan;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.CtApiDAO;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthTokenResponse;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileReputationResult;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud.CTLicensePersistence;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Blackboard;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.Score;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses CT cloud API to determine if file is malware
|
||||||
|
*/
|
||||||
|
public class MalwareScanIngestModule implements FileIngestModule {
|
||||||
|
|
||||||
|
private static final SharedProcessing sharedProcessing = new SharedProcessing();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
sharedProcessing.startUp(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(AbstractFile af) {
|
||||||
|
return sharedProcessing.process(af);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown() {
|
||||||
|
sharedProcessing.shutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the bulk of processing for the ingest module and handles concurrent
|
||||||
|
* ingest modules adding files simultaneously.
|
||||||
|
*/
|
||||||
|
private static class SharedProcessing {
|
||||||
|
|
||||||
|
// batch size of 200 files max
|
||||||
|
private static final int BATCH_SIZE = 200;
|
||||||
|
// 3 minute timeout for an API request
|
||||||
|
private static final long BATCH_MILLIS_TIMEOUT = 3 * 60 * 1000;
|
||||||
|
|
||||||
|
//minimum lookups left before issuing warning
|
||||||
|
private static final long LOW_LOOKUPS_REMAINING = 250;
|
||||||
|
|
||||||
|
private static final Set<String> EXECUTABLE_MIME_TYPES = Stream.of(
|
||||||
|
"application/x-bat",//NON-NLS
|
||||||
|
"application/x-dosexec",//NON-NLS
|
||||||
|
"application/vnd.microsoft.portable-executable",//NON-NLS
|
||||||
|
"application/x-msdownload",//NON-NLS
|
||||||
|
"application/exe",//NON-NLS
|
||||||
|
"application/x-exe",//NON-NLS
|
||||||
|
"application/dos-exe",//NON-NLS
|
||||||
|
"vms/exe",//NON-NLS
|
||||||
|
"application/x-winexe",//NON-NLS
|
||||||
|
"application/msdos-windows",//NON-NLS
|
||||||
|
"application/x-msdos-program"//NON-NLS
|
||||||
|
).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
private static final String MALWARE_TYPE_NAME = "TSK_MALWARE";
|
||||||
|
private static final String MALWARE_CONFIG = "Cyber Triage Cloud";
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(MalwareScanIngestModule.class.getName());
|
||||||
|
private final BatchProcessor<FileRecord> batchProcessor = new BatchProcessor<FileRecord>(BATCH_SIZE, BATCH_MILLIS_TIMEOUT, this::handleBatch);
|
||||||
|
|
||||||
|
private final CTLicensePersistence ctSettingsPersistence = CTLicensePersistence.getInstance();
|
||||||
|
private final CtApiDAO ctApiDAO = CtApiDAO.getInstance();
|
||||||
|
|
||||||
|
private FileTypeDetector fileTypeDetector;
|
||||||
|
private RunState runState = null;
|
||||||
|
private SleuthkitCase tskCase = null;
|
||||||
|
private LicenseInfo licenseInfo = null;
|
||||||
|
private BlackboardArtifact.Type malwareType = null;
|
||||||
|
private boolean noMoreHashLookups = false;
|
||||||
|
private IngestModuleException startupException;
|
||||||
|
private long dsId = 0;
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModule_ShareProcessing_lowLimitWarning_title=Hash Lookups Low",
|
||||||
|
"# {0} - remainingLookups",
|
||||||
|
"MalwareScanIngestModule_ShareProcessing_lowLimitWarning_desc=This license only has {0} lookups remaining",
|
||||||
|
"MalwareScanIngestModule_malwareTypeDisplayName=Malware"
|
||||||
|
})
|
||||||
|
synchronized void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
// only run this code once per startup
|
||||||
|
if (runState == RunState.STARTED_UP) {
|
||||||
|
if (startupException != null) {
|
||||||
|
throw startupException;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// get saved license
|
||||||
|
Optional<LicenseInfo> licenseInfoOpt = ctSettingsPersistence.loadLicenseInfo();
|
||||||
|
if (licenseInfoOpt.isEmpty() || licenseInfoOpt.get().getDecryptedLicense() == null) {
|
||||||
|
throw new IngestModuleException("No saved license was found");
|
||||||
|
}
|
||||||
|
|
||||||
|
String licenseStr = licenseInfoOpt.get().getDecryptedLicense().getBoostLicenseId();
|
||||||
|
AuthTokenResponse authTokenResponse = ctApiDAO.getAuthToken(licenseStr);
|
||||||
|
// syncronously fetch malware scans info
|
||||||
|
|
||||||
|
// determine lookups remaining
|
||||||
|
long lookupsRemaining = remaining(authTokenResponse.getHashLookupLimit(), authTokenResponse.getHashLookupCount());
|
||||||
|
if (lookupsRemaining <= 0) {
|
||||||
|
throw new IngestModuleException("There are no more file hash lookups for this license");
|
||||||
|
} else if (lookupsRemaining < LOW_LOOKUPS_REMAINING) {
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_ShareProcessing_lowLimitWarning_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_ShareProcessing_lowLimitWarning_desc(lookupsRemaining),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup necessary variables for processing
|
||||||
|
tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
malwareType = tskCase.getBlackboard().getOrAddArtifactType(
|
||||||
|
MALWARE_TYPE_NAME,
|
||||||
|
Bundle.MalwareScanIngestModule_malwareTypeDisplayName(),
|
||||||
|
BlackboardArtifact.Category.ANALYSIS_RESULT);
|
||||||
|
fileTypeDetector = new FileTypeDetector();
|
||||||
|
dsId = context.getDataSource().getId();
|
||||||
|
licenseInfo = licenseInfoOpt.get();
|
||||||
|
startupException = null;
|
||||||
|
noMoreHashLookups = false;
|
||||||
|
} catch (IngestModuleException ex) {
|
||||||
|
startupException = ex;
|
||||||
|
throw startupException;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
startupException = new IngestModuleException("An exception occurred on MalwareScanIngestModule startup", ex);
|
||||||
|
throw startupException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long remaining(Long limit, Long used) {
|
||||||
|
limit = limit == null ? 0 : limit;
|
||||||
|
used = used == null ? 0 : used;
|
||||||
|
return limit - used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModule_ShareProcessing_batchTimeout_title=Batch Processing Timeout",
|
||||||
|
"MalwareScanIngestModule_ShareProcessing_batchTimeout_desc=Batch processing timed out"
|
||||||
|
})
|
||||||
|
IngestModule.ProcessResult process(AbstractFile af) {
|
||||||
|
try {
|
||||||
|
if (af.getKnown() != TskData.FileKnown.KNOWN
|
||||||
|
&& EXECUTABLE_MIME_TYPES.contains(StringUtils.defaultString(fileTypeDetector.getMIMEType(af)).trim().toLowerCase())) {
|
||||||
|
batchProcessor.add(new FileRecord(af.getId(), af.getMd5Hash()));
|
||||||
|
|
||||||
|
}
|
||||||
|
return ProcessResult.OK;
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_ShareProcessing_batchTimeout_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_ShareProcessing_batchTimeout_desc(),
|
||||||
|
ex);
|
||||||
|
return IngestModule.ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_authTokenResponseError_title=Authentication API error",
|
||||||
|
"# {0} - errorResponse",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_authTokenResponseError_desc=Received error: ''{0}'' when fetching the API authentication token for the license",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_repServicenResponseError_title=Lookup API error",
|
||||||
|
"# {0} - errorResponse",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_repServicenResponseError_desc=Received error: ''{0}'' when fetching hash lookup results",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title=Hash Lookups Exhausted",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc=The remaining hash lookups for this license have been exhausted",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_generalProcessingError_title=Hash Lookup Error",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc=An error occurred while processing hash lookup results",})
|
||||||
|
private void handleBatch(List<FileRecord> fileRecords) {
|
||||||
|
if (fileRecords == null || fileRecords.isEmpty() || noMoreHashLookups) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create mapping of md5 to corresponding object ids as well as just the list of md5's
|
||||||
|
Map<String, List<Long>> md5ToObjId = new HashMap<>();
|
||||||
|
List<String> md5Hashes = new ArrayList<>();
|
||||||
|
for (FileRecord fr : fileRecords) {
|
||||||
|
if (fr == null || StringUtils.isBlank(fr.getMd5hash()) || fr.getObjId() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sanitizedMd5 = sanitizedMd5(fr.getMd5hash());
|
||||||
|
md5ToObjId
|
||||||
|
.computeIfAbsent(sanitizedMd5, (k) -> new ArrayList<>())
|
||||||
|
.add(fr.getObjId());
|
||||||
|
|
||||||
|
md5Hashes.add(sanitizedMd5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md5Hashes.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// get an auth token with the license
|
||||||
|
AuthTokenResponse authTokenResponse = ctApiDAO.getAuthToken(licenseInfo.getDecryptedLicense().getBoostLicenseId());
|
||||||
|
|
||||||
|
// make sure we are in bounds for the remaining scans
|
||||||
|
long remainingScans = remaining(authTokenResponse.getHashLookupLimit(), authTokenResponse.getHashLookupCount());
|
||||||
|
if (remainingScans <= 0) {
|
||||||
|
noMoreHashLookups = true;
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc(),
|
||||||
|
null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the size of this batch will exceed limit, shrink list to limit and fail after processing
|
||||||
|
boolean exceededScanLimit = false;
|
||||||
|
if (remainingScans < md5Hashes.size()) {
|
||||||
|
md5Hashes = md5Hashes.subList(0, (int) remainingScans);
|
||||||
|
exceededScanLimit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// using auth token, get results
|
||||||
|
List<FileReputationResult> repResult = ctApiDAO.getReputationResults(authTokenResponse.getToken(), md5Hashes);
|
||||||
|
|
||||||
|
if (repResult != null && !repResult.isEmpty()) {
|
||||||
|
SleuthkitCase.CaseDbTransaction trans = null;
|
||||||
|
try {
|
||||||
|
trans = tskCase.beginTransaction();
|
||||||
|
for (FileReputationResult result : repResult) {
|
||||||
|
String sanitizedMd5 = sanitizedMd5(result.getMd5Hash());
|
||||||
|
List<Long> objIds = md5ToObjId.remove(sanitizedMd5);
|
||||||
|
if (objIds == null || objIds.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Long objId : objIds) {
|
||||||
|
createAnalysisResult(objId, result, trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trans.commit();
|
||||||
|
trans = null;
|
||||||
|
} finally {
|
||||||
|
if (trans != null) {
|
||||||
|
trans.rollback();
|
||||||
|
trans = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we only processed part of the batch, after processing, notify that we are out of scans.
|
||||||
|
if (exceededScanLimit) {
|
||||||
|
noMoreHashLookups = true;
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc(),
|
||||||
|
null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc(),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sanitizedMd5(String orig) {
|
||||||
|
return StringUtils.defaultString(orig).trim().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_createAnalysisResult_Yes=YES",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No=NO"
|
||||||
|
})
|
||||||
|
private void createAnalysisResult(Long objId, FileReputationResult fileReputationResult, SleuthkitCase.CaseDbTransaction trans) throws Blackboard.BlackboardException {
|
||||||
|
if (objId == null || fileReputationResult == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Score score = fileReputationResult.getScore() == null ? Score.SCORE_UNKNOWN : fileReputationResult.getScore().getTskCore();
|
||||||
|
|
||||||
|
String conclusion = score.getSignificance() == Score.Significance.NOTABLE || score.getSignificance() == Score.Significance.LIKELY_NOTABLE
|
||||||
|
? Bundle.MalwareScanIngestModule_SharedProcessing_createAnalysisResult_Yes()
|
||||||
|
: Bundle.MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No();
|
||||||
|
|
||||||
|
String justification = fileReputationResult.getStatusDescription();
|
||||||
|
|
||||||
|
tskCase.getBlackboard().newAnalysisResult(
|
||||||
|
malwareType,
|
||||||
|
objId,
|
||||||
|
dsId,
|
||||||
|
score,
|
||||||
|
conclusion,
|
||||||
|
MALWARE_CONFIG,
|
||||||
|
justification,
|
||||||
|
Collections.emptyList(),
|
||||||
|
trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_flushTimeout_title=Processing Timeout",
|
||||||
|
"MalwareScanIngestModule_SharedProcessing_flushTimeout_desc=A timeout occurred while finishing processing"
|
||||||
|
})
|
||||||
|
synchronized void shutDown() {
|
||||||
|
// if already shut down, return
|
||||||
|
if (runState == RunState.SHUT_DOWN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush any remaining items
|
||||||
|
try {
|
||||||
|
batchProcessor.flush(true);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
notifyWarning(
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_flushTimeout_title(),
|
||||||
|
Bundle.MalwareScanIngestModule_SharedProcessing_flushTimeout_desc(),
|
||||||
|
ex);
|
||||||
|
} finally {
|
||||||
|
// set state to shut down and clear any remaining
|
||||||
|
malwareType = null;
|
||||||
|
fileTypeDetector = null;
|
||||||
|
noMoreHashLookups = false;
|
||||||
|
runState = RunState.SHUT_DOWN;
|
||||||
|
startupException = null;
|
||||||
|
batchProcessor.clearCurrentBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyWarning(String title, String message, Exception ex) {
|
||||||
|
MessageNotifyUtil.Notify.warn(title, message);
|
||||||
|
logger.log(Level.WARNING, message, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum RunState {
|
||||||
|
STARTED_UP, SHUT_DOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileRecord {
|
||||||
|
|
||||||
|
private final long objId;
|
||||||
|
private final String md5hash;
|
||||||
|
|
||||||
|
FileRecord(long objId, String md5hash) {
|
||||||
|
this.objId = objId;
|
||||||
|
this.md5hash = md5hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
long getObjId() {
|
||||||
|
return objId;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMd5hash() {
|
||||||
|
return md5hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/** *************************************************************************
|
||||||
|
** This data and information is proprietary to, and a valuable trade secret
|
||||||
|
** of, Basis Technology Corp. It is given in confidence by Basis Technology
|
||||||
|
** and may only be used as permitted under the license agreement under which
|
||||||
|
** it has been distributed, and in no other way.
|
||||||
|
**
|
||||||
|
** Copyright (c) 2023 Basis Technology Corp. All rights reserved.
|
||||||
|
**
|
||||||
|
** The technical data and information provided herein are provided with
|
||||||
|
** `limited rights', and the computer software provided herein is provided
|
||||||
|
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||||
|
** 7-104.9(a).
|
||||||
|
************************************************************************** */
|
||||||
|
package com.basistech.df.cybertriage.autopsy.malwarescan;
|
||||||
|
|
||||||
|
import com.basistech.df.cybertriage.autopsy.ctoptions.CTOptionsPanel;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for malware scan ingest modules.
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = org.sleuthkit.autopsy.ingest.IngestModuleFactory.class)
|
||||||
|
@Messages({
|
||||||
|
"MalwareScanIngestModuleFactory_displayName=Malware Scan",
|
||||||
|
"MalwareScanIngestModuleFactory_description=The malware scan ingest module queries the CyberTriage cloud API for any possible malicious executables.",
|
||||||
|
"MalwareScanIngestModuleFactory_version=1.0.0"
|
||||||
|
})
|
||||||
|
public class MalwareScanIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDisplayName() {
|
||||||
|
return Bundle.MalwareScanIngestModuleFactory_displayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDescription() {
|
||||||
|
return Bundle.MalwareScanIngestModuleFactory_description();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleVersionNumber() {
|
||||||
|
return Bundle.MalwareScanIngestModuleFactory_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) {
|
||||||
|
return new MalwareScanIngestModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasGlobalSettingsPanel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
|
||||||
|
CTOptionsPanel optionsPanel = new CTOptionsPanel();
|
||||||
|
optionsPanel.loadSavedSettings();
|
||||||
|
return optionsPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE ivy-module [
|
<!DOCTYPE ivy-module [
|
||||||
<!ENTITY javafx.version "17.0.7">
|
<!ENTITY javafx.version "17.0.7">
|
||||||
|
<!ENTITY jackson.version "2.15.2">
|
||||||
]>
|
]>
|
||||||
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
|
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
|
||||||
<info organisation="org.sleuthkit.autopsy" module="corelibs"/>
|
<info organisation="org.sleuthkit.autopsy" module="corelibs"/>
|
||||||
@ -87,7 +88,8 @@
|
|||||||
|
|
||||||
<dependency conf="autopsy_core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.4"/>
|
<dependency conf="autopsy_core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.4"/>
|
||||||
|
|
||||||
<dependency conf="autopsy_core->default" org="com.fasterxml.jackson.dataformat" name="jackson-dataformat-csv" rev="2.15.2"/>
|
<dependency conf="autopsy_core->default" org="com.fasterxml.jackson.dataformat" name="jackson-dataformat-csv" rev="&jackson.version;"/>
|
||||||
|
<dependency conf="autopsy_core->default" org="com.fasterxml.jackson.datatype" name="jackson-datatype-jsr310" rev="&jackson.version;"/>
|
||||||
|
|
||||||
<!-- better image resizing -->
|
<!-- better image resizing -->
|
||||||
<dependency conf="autopsy_core->default" org="org.imgscalr" name="imgscalr-lib" rev="4.2" />
|
<dependency conf="autopsy_core->default" org="org.imgscalr" name="imgscalr-lib" rev="4.2" />
|
||||||
@ -142,8 +144,8 @@
|
|||||||
|
|
||||||
<override org="com.google.code.gson" module="gson" rev="2.9.0"/>
|
<override org="com.google.code.gson" module="gson" rev="2.9.0"/>
|
||||||
<override org="com.google.guava" module="guava" rev="32.0.1-jre"/>
|
<override org="com.google.guava" module="guava" rev="32.0.1-jre"/>
|
||||||
<override org="com.fasterxml.jackson.core" module="jackson-databind" rev="2.15.2"/>
|
<override org="com.fasterxml.jackson.core" module="jackson-databind" rev="&jackson.version;"/>
|
||||||
<override org="com.fasterxml.jackson.core" module="jackson-core" rev="2.15.2"/>
|
<override org="com.fasterxml.jackson.core" module="jackson-core" rev="&jackson.version;"/>
|
||||||
|
|
||||||
<!-- changes to bouncy castle version may also be reflected in thirdparty/IcePDF 6.2.2 -->
|
<!-- changes to bouncy castle version may also be reflected in thirdparty/IcePDF 6.2.2 -->
|
||||||
<override org="org.bouncycastle" module="bcprov-jdk15on" rev="1.70"/>
|
<override org="org.bouncycastle" module="bcprov-jdk15on" rev="1.70"/>
|
||||||
|
@ -11,4 +11,4 @@ Specification-Version: 1.0
|
|||||||
Specification-Vendor: CoreLibs ImageIO Fields
|
Specification-Vendor: CoreLibs ImageIO Fields
|
||||||
Implementation-Title: org.sleuthkit.autopsy.corelibs.ImageIO
|
Implementation-Title: org.sleuthkit.autopsy.corelibs.ImageIO
|
||||||
Implementation-Version: 1.0
|
Implementation-Version: 1.0
|
||||||
Implementation-Vendor: CoreLibs ImageIO Fields
|
Implementation-Vendor: CoreLibs ImageIO Fields
|
||||||
|
@ -84,6 +84,7 @@ file.reference.jackson-annotations-2.15.2.jar=release/modules/ext/jackson-annota
|
|||||||
file.reference.jackson-core-2.15.2.jar=release/modules/ext/jackson-core-2.15.2.jar
|
file.reference.jackson-core-2.15.2.jar=release/modules/ext/jackson-core-2.15.2.jar
|
||||||
file.reference.jackson-databind-2.15.2.jar=release/modules/ext/jackson-databind-2.15.2.jar
|
file.reference.jackson-databind-2.15.2.jar=release/modules/ext/jackson-databind-2.15.2.jar
|
||||||
file.reference.jackson-dataformat-csv-2.15.2.jar=release/modules/ext/jackson-dataformat-csv-2.15.2.jar
|
file.reference.jackson-dataformat-csv-2.15.2.jar=release/modules/ext/jackson-dataformat-csv-2.15.2.jar
|
||||||
|
file.reference.jackson-datatype-jsr310-2.15.2.jar=release/modules/ext/jackson-datatype-jsr310-2.15.2.jar
|
||||||
file.reference.javafx-base-17.0.7-linux.jar=release/modules/ext/javafx-base-17.0.7-linux.jar
|
file.reference.javafx-base-17.0.7-linux.jar=release/modules/ext/javafx-base-17.0.7-linux.jar
|
||||||
file.reference.javafx-base-17.0.7-mac.jar=release/modules/ext/javafx-base-17.0.7-mac.jar
|
file.reference.javafx-base-17.0.7-mac.jar=release/modules/ext/javafx-base-17.0.7-mac.jar
|
||||||
file.reference.javafx-base-17.0.7-win.jar=release/modules/ext/javafx-base-17.0.7-win.jar
|
file.reference.javafx-base-17.0.7-win.jar=release/modules/ext/javafx-base-17.0.7-win.jar
|
||||||
|
@ -63,6 +63,8 @@
|
|||||||
<package>com.fasterxml.jackson.databind.type</package>
|
<package>com.fasterxml.jackson.databind.type</package>
|
||||||
<package>com.fasterxml.jackson.databind.util</package>
|
<package>com.fasterxml.jackson.databind.util</package>
|
||||||
<package>com.fasterxml.jackson.dataformat.csv</package>
|
<package>com.fasterxml.jackson.dataformat.csv</package>
|
||||||
|
<package>com.fasterxml.jackson.datatype.jsr310</package>
|
||||||
|
<package>com.fasterxml.jackson.datatype.jsr310.util</package>
|
||||||
<package>com.github.lgooddatepicker.components</package>
|
<package>com.github.lgooddatepicker.components</package>
|
||||||
<package>com.github.lgooddatepicker.optionalusertools</package>
|
<package>com.github.lgooddatepicker.optionalusertools</package>
|
||||||
<package>com.github.lgooddatepicker.zinternaltools</package>
|
<package>com.github.lgooddatepicker.zinternaltools</package>
|
||||||
@ -197,8 +199,6 @@
|
|||||||
<package>com.google.rpc.context</package>
|
<package>com.google.rpc.context</package>
|
||||||
<package>com.google.thirdparty.publicsuffix</package>
|
<package>com.google.thirdparty.publicsuffix</package>
|
||||||
<package>com.google.type</package>
|
<package>com.google.type</package>
|
||||||
<package>com.microsoft.schemas.vml</package>
|
|
||||||
<package>com.microsoft.schemas.vml.impl</package>
|
|
||||||
<package>com.sun.javafx</package>
|
<package>com.sun.javafx</package>
|
||||||
<package>com.sun.javafx.animation</package>
|
<package>com.sun.javafx.animation</package>
|
||||||
<package>com.sun.javafx.application</package>
|
<package>com.sun.javafx.application</package>
|
||||||
@ -321,9 +321,6 @@
|
|||||||
<package>com.twelvemonkeys.util.regex</package>
|
<package>com.twelvemonkeys.util.regex</package>
|
||||||
<package>com.twelvemonkeys.util.service</package>
|
<package>com.twelvemonkeys.util.service</package>
|
||||||
<package>com.twelvemonkeys.xml</package>
|
<package>com.twelvemonkeys.xml</package>
|
||||||
<package>javax.annotation</package>
|
|
||||||
<package>javax.annotation.concurrent</package>
|
|
||||||
<package>javax.annotation.meta</package>
|
|
||||||
<package>javafx.animation</package>
|
<package>javafx.animation</package>
|
||||||
<package>javafx.application</package>
|
<package>javafx.application</package>
|
||||||
<package>javafx.beans</package>
|
<package>javafx.beans</package>
|
||||||
@ -340,7 +337,6 @@
|
|||||||
<package>javafx.event</package>
|
<package>javafx.event</package>
|
||||||
<package>javafx.fxml</package>
|
<package>javafx.fxml</package>
|
||||||
<package>javafx.geometry</package>
|
<package>javafx.geometry</package>
|
||||||
<package>javafx.graphics</package>
|
|
||||||
<package>javafx.print</package>
|
<package>javafx.print</package>
|
||||||
<package>javafx.scene</package>
|
<package>javafx.scene</package>
|
||||||
<package>javafx.scene.canvas</package>
|
<package>javafx.scene.canvas</package>
|
||||||
@ -362,19 +358,9 @@
|
|||||||
<package>javafx.stage</package>
|
<package>javafx.stage</package>
|
||||||
<package>javafx.util</package>
|
<package>javafx.util</package>
|
||||||
<package>javafx.util.converter</package>
|
<package>javafx.util.converter</package>
|
||||||
<package>javax.jms</package>
|
<package>javax.annotation</package>
|
||||||
<package>javax.mail</package>
|
<package>javax.annotation.concurrent</package>
|
||||||
<package>javax.mail.event</package>
|
<package>javax.annotation.meta</package>
|
||||||
<package>javax.mail.internet</package>
|
|
||||||
<package>javax.mail.search</package>
|
|
||||||
<package>javax.mail.util</package>
|
|
||||||
<package>javax.servlet</package>
|
|
||||||
<package>javax.servlet.http</package>
|
|
||||||
<package>javax.xml.parsers</package>
|
|
||||||
<package>javax.xml.transform</package>
|
|
||||||
<package>javax.xml.transform.dom</package>
|
|
||||||
<package>javax.xml.transform.sax</package>
|
|
||||||
<package>javax.xml.transform.stream</package>
|
|
||||||
<package>jfxtras.animation</package>
|
<package>jfxtras.animation</package>
|
||||||
<package>jfxtras.css</package>
|
<package>jfxtras.css</package>
|
||||||
<package>jfxtras.css.converters</package>
|
<package>jfxtras.css.converters</package>
|
||||||
@ -442,16 +428,6 @@
|
|||||||
<package>org.apache.commons.lang3.tuple</package>
|
<package>org.apache.commons.lang3.tuple</package>
|
||||||
<package>org.apache.commons.logging</package>
|
<package>org.apache.commons.logging</package>
|
||||||
<package>org.apache.commons.logging.impl</package>
|
<package>org.apache.commons.logging.impl</package>
|
||||||
<package>org.apache.log</package>
|
|
||||||
<package>org.apache.log.filter</package>
|
|
||||||
<package>org.apache.log.format</package>
|
|
||||||
<package>org.apache.log.output</package>
|
|
||||||
<package>org.apache.log.output.db</package>
|
|
||||||
<package>org.apache.log.output.io</package>
|
|
||||||
<package>org.apache.log.output.io.rotate</package>
|
|
||||||
<package>org.apache.log.output.jms</package>
|
|
||||||
<package>org.apache.log.output.net</package>
|
|
||||||
<package>org.apache.log.util</package>
|
|
||||||
<package>org.apache.commons.text</package>
|
<package>org.apache.commons.text</package>
|
||||||
<package>org.apache.commons.validator.routines</package>
|
<package>org.apache.commons.validator.routines</package>
|
||||||
<package>org.apache.commons.validator.routines.checkdigit</package>
|
<package>org.apache.commons.validator.routines.checkdigit</package>
|
||||||
@ -460,14 +436,7 @@
|
|||||||
<package>org.apache.log4j.config</package>
|
<package>org.apache.log4j.config</package>
|
||||||
<package>org.apache.log4j.helpers</package>
|
<package>org.apache.log4j.helpers</package>
|
||||||
<package>org.apache.log4j.jdbc</package>
|
<package>org.apache.log4j.jdbc</package>
|
||||||
<package>org.apache.log4j.jmx</package>
|
|
||||||
<package>org.apache.log4j.lf5</package>
|
|
||||||
<package>org.apache.log4j.lf5.util</package>
|
|
||||||
<package>org.apache.log4j.lf5.viewer</package>
|
|
||||||
<package>org.apache.log4j.lf5.viewer.categoryexplorer</package>
|
|
||||||
<package>org.apache.log4j.lf5.viewer.configure</package>
|
|
||||||
<package>org.apache.log4j.net</package>
|
<package>org.apache.log4j.net</package>
|
||||||
<package>org.apache.log4j.nt</package>
|
|
||||||
<package>org.apache.log4j.or</package>
|
<package>org.apache.log4j.or</package>
|
||||||
<package>org.apache.log4j.or.jms</package>
|
<package>org.apache.log4j.or.jms</package>
|
||||||
<package>org.apache.log4j.or.sax</package>
|
<package>org.apache.log4j.or.sax</package>
|
||||||
@ -931,6 +900,10 @@
|
|||||||
<runtime-relative-path>ext/jackson-dataformat-csv-2.15.2.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jackson-dataformat-csv-2.15.2.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/jackson-dataformat-csv-2.15.2.jar</binary-origin>
|
<binary-origin>release/modules/ext/jackson-dataformat-csv-2.15.2.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/jackson-datatype-jsr310-2.15.2.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/jackson-datatype-jsr310-2.15.2.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/javafx-base-17.0.7-linux.jar</runtime-relative-path>
|
<runtime-relative-path>ext/javafx-base-17.0.7-linux.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/javafx-base-17.0.7-linux.jar</binary-origin>
|
<binary-origin>release/modules/ext/javafx-base-17.0.7-linux.jar</binary-origin>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Wed, 28 Sep 2022 13:57:05 -0400
|
#Thu, 20 Jul 2023 14:02:30 -0400
|
||||||
LBL_splash_window_title=Starting Autopsy
|
LBL_splash_window_title=Starting Autopsy
|
||||||
SPLASH_HEIGHT=314
|
SPLASH_HEIGHT=314
|
||||||
SPLASH_WIDTH=538
|
SPLASH_WIDTH=538
|
||||||
@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18
|
|||||||
SplashRunningTextColor=0x0
|
SplashRunningTextColor=0x0
|
||||||
SplashRunningTextFontSize=19
|
SplashRunningTextFontSize=19
|
||||||
|
|
||||||
currentVersion=Autopsy 4.19.3
|
currentVersion=Autopsy 4.20.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Wed, 28 Sep 2022 13:57:05 -0400
|
#Thu, 20 Jul 2023 14:02:30 -0400
|
||||||
CTL_MainWindow_Title=Autopsy 4.19.3
|
CTL_MainWindow_Title=Autopsy 4.20.0
|
||||||
CTL_MainWindow_Title_No_Project=Autopsy 4.19.3
|
CTL_MainWindow_Title_No_Project=Autopsy 4.20.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user