From 6e5e2ff2f53fd3bbda4776003496628d0955cf1e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 23 Aug 2023 12:59:58 -0400 Subject: [PATCH 1/8] fix for local app data on non-windows systems --- .../df/cybertriage/autopsy/incidentoptions/CTSettings.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java index 35e2d108ea..67abb34f7b 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java @@ -20,6 +20,7 @@ import java.nio.file.Paths; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.lang3.StringUtils; import org.openide.modules.Places; /** @@ -38,7 +39,11 @@ public class CTSettings { LOGGER.log(Level.INFO, "Application Data (test mode) Path: " + Places.getUserDirectory().getAbsolutePath()); return Places.getUserDirectory().getAbsolutePath(); } else { - Path localAppPath = Paths.get(System.getenv("LOCALAPPDATA"), "cybertriage"); + + Path localAppPath = StringUtils.isBlank(System.getenv("LOCALAPPDATA")) + ? Places.getUserDirectory().toPath().toAbsolutePath() + : Paths.get(System.getenv("LOCALAPPDATA"), "cybertriage"); + try { Files.createDirectories(localAppPath); LOGGER.log(Level.INFO, "Application Data Path: " + localAppPath.toString()); From 0bec001773e64a70c15c99790fd346be180c1656 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 24 Aug 2023 14:10:59 -0400 Subject: [PATCH 2/8] fixes --- .../autopsy/ctoptions/CTOptionsPanel.java | 2 +- .../ctcloud/CTMalwareScannerOptionsPanel.java | 2 +- .../CTIncidentImportOptionsPanel.java | 33 ++++---- .../autopsy/incidentoptions/CTSettings.java | 79 ++++++++++++------- .../CTSettingsPersistence.java | 31 +++++--- 5 files changed, 91 insertions(+), 56 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java index 83a4a9a51a..2b6cffe789 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java @@ -26,12 +26,12 @@ 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.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; /** diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java index 375943188c..3c71bd3cba 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java @@ -40,7 +40,6 @@ import java.util.Optional; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; @@ -51,6 +50,7 @@ import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.coreutils.Logger; /** * Options panel to be displayed in the CTOptionsPanel for settings regarding diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java index bf018701ca..ef7aa5a67e 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java @@ -1,16 +1,21 @@ -/** ************************************************************************* - ** This data and information is proprietary to, and a valuable trade secret - ** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs - ** 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 Sleuth Kit Labs, LLC. 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). - ************************************************************************** */ +/* + * Autopsy Forensic Browser + * + * Copyright 2023 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.basistech.df.cybertriage.autopsy.incidentoptions; import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel; @@ -21,7 +26,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.logging.Level; -import java.util.logging.Logger; +import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.JFileChooser; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java index 67abb34f7b..d6427a641c 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java @@ -1,16 +1,21 @@ -/** ************************************************************************* - ** This data and information is proprietary to, and a valuable trade secret - ** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs - ** 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 Sleuth Kit Labs, LLC. 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). - ************************************************************************** */ +/* + * Autopsy Forensic Browser + * + * Copyright 2023 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.basistech.df.cybertriage.autopsy.incidentoptions; import java.io.IOException; @@ -19,40 +24,60 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Objects; import java.util.logging.Level; -import java.util.logging.Logger; +import org.sleuthkit.autopsy.coreutils.Logger; import org.apache.commons.lang3.StringUtils; import org.openide.modules.Places; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** - * CT settings that don't include license information. This code must be kept in-sync with code in - * CT Autopsy Importer NBM. + * CT settings that don't include license information. This code must be kept + * in-sync with code in CT Autopsy Importer NBM. */ public class CTSettings { + private static final Logger LOGGER = Logger.getLogger(CTSettings.class.getCanonicalName()); private static final String DEFAULT_FILE_REPO_PATH = getAppDataLocalDirectory(); - // taken from com.basistech.df.cybertriage.utils.SystemProperties - private static String getAppDataLocalDirectory() { + private static final String CYBERTRIAGE_FOLDER = "cybertriage"; + private static final String CYBERTRIAGE_DOT_FOLDER = "." + CYBERTRIAGE_FOLDER; - Logger LOGGER = java.util.logging.Logger.getLogger(CTSettings.class.getCanonicalName()); + // based on com.basistech.df.cybertriage.utils.SystemProperties + private static String getAppDataLocalDirectory() { if (Objects.nonNull(Places.getUserDirectory()) && Places.getUserDirectory().getAbsolutePath().endsWith("testuserdir")) { // APP is in testing .. this should return the test path LOGGER.log(Level.INFO, "Application Data (test mode) Path: " + Places.getUserDirectory().getAbsolutePath()); return Places.getUserDirectory().getAbsolutePath(); - } else { - - Path localAppPath = StringUtils.isBlank(System.getenv("LOCALAPPDATA")) - ? Places.getUserDirectory().toPath().toAbsolutePath() - : Paths.get(System.getenv("LOCALAPPDATA"), "cybertriage"); - + } + + // try to use LOCALAPPDATA on windows + String localDataStr = System.getenv("LOCALAPPDATA"); + if (StringUtils.isNotBlank(localDataStr)) { + Path localAppPath = Paths.get(localDataStr, CYBERTRIAGE_FOLDER); try { Files.createDirectories(localAppPath); LOGGER.log(Level.INFO, "Application Data Path: " + localAppPath.toString()); return localAppPath.toString(); } catch (IOException ex) { - LOGGER.log(Level.SEVERE, "IO Error, defaulting to user dir", ex); - return Places.getUserDirectory().getAbsolutePath(); // In case of an IO Error + LOGGER.log(Level.SEVERE, "IO Error using " + localAppPath.toString(), ex); } } + + // try to use ~/.cybertriage anywhere else + if (!PlatformUtil.isWindowsOS()) { + String homePathStr = System.getenv("HOME"); + if (StringUtils.isNotBlank(homePathStr)) { + Path localAppPath = Paths.get(homePathStr, CYBERTRIAGE_DOT_FOLDER); + try { + Files.createDirectories(localAppPath); + LOGGER.log(Level.INFO, "Non-windows Application Data Path: " + localAppPath.toString()); + return localAppPath.toString(); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, "IO Error using " + localAppPath.toString(), ex); + } + } + } + + // defer to user directory otherwise + return Places.getUserDirectory().getAbsolutePath(); // In case of an IO Error } public static String getDefaultFileRepoPath() { diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java index be60813edd..e5e5b6838f 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java @@ -1,16 +1,21 @@ -/** ************************************************************************* - ** This data and information is proprietary to, and a valuable trade secret - ** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs - ** 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 Sleuth Kit Labs, LLC. 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). - ************************************************************************** */ +/* + * Autopsy Forensic Browser + * + * Copyright 2023 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.basistech.df.cybertriage.autopsy.incidentoptions; import com.fasterxml.jackson.databind.ObjectMapper; From ed444f466141c70f552ae0591b1ad99fbdeb7a58 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 24 Aug 2023 15:22:40 -0400 Subject: [PATCH 3/8] better feedback on unsuccessful license --- .../autopsy/ctapi/json/LicenseResponse.java | 9 +++++- .../ctapi/util/LicenseDecryptorUtil.java | 19 ++++++++--- .../ctcloud/Bundle.properties-MERGED | 2 ++ .../ctcloud/CTMalwareScannerOptionsPanel.java | 32 ++++++++++++++++--- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/json/LicenseResponse.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/json/LicenseResponse.java index a3a8247884..5a85778b60 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/json/LicenseResponse.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/json/LicenseResponse.java @@ -32,18 +32,21 @@ public class LicenseResponse { private final Boolean hostChanged; private final Long hostChangesRemaining; private final BoostLicenseResponse boostLicense; + private final String errorMsg; @JsonCreator public LicenseResponse( @JsonProperty("success") Boolean success, @JsonProperty("hostChanged") Boolean hostChanged, @JsonProperty("hostChangesRemaining") Long hostChangesRemaining, - @JsonProperty("boostLicense") BoostLicenseResponse boostLicense + @JsonProperty("boostLicense") BoostLicenseResponse boostLicense, + @JsonProperty("errorMsg") String errorMsg ) { this.success = success; this.hostChanged = hostChanged; this.hostChangesRemaining = hostChangesRemaining; this.boostLicense = boostLicense; + this.errorMsg = errorMsg; } public Boolean isSuccess() { @@ -61,4 +64,8 @@ public class LicenseResponse { public BoostLicenseResponse getBoostLicense() { return boostLicense; } + + public String getErrorMsg() { + return errorMsg; + } } diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/util/LicenseDecryptorUtil.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/util/LicenseDecryptorUtil.java index f62b57d795..26ebe793a4 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/util/LicenseDecryptorUtil.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/util/LicenseDecryptorUtil.java @@ -34,6 +34,7 @@ import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.X509EncodedKeySpec; +import java.text.MessageFormat; import java.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -42,6 +43,7 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import org.apache.commons.lang3.ObjectUtils; /** * Decrypts the payload of boost license. @@ -58,12 +60,12 @@ public class LicenseDecryptorUtil { 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"); + if (licenseResponse == null) { + throw new InvalidLicenseException("License is null"); } - + DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense()); return new LicenseInfo(licenseResponse, decrypted); } @@ -78,6 +80,9 @@ public class LicenseDecryptorUtil { * com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException */ public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException { + if (licenseResponse == null) { + throw new InvalidLicenseException("Boost license is null"); + } String decryptedJsonResponse; try { @@ -101,6 +106,12 @@ public class LicenseDecryptorUtil { } private String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version) throws IOException, GeneralSecurityException, InvalidLicenseException { + if (ObjectUtils.anyNull(encryptedJson, ivBase64, encryptedKey, version)) { + throw new InvalidLicenseException(MessageFormat.format( + "encryptedJson: {0}, iv: {1}, encryptedKey: {2}, version: {3} must all be non-null", + encryptedJson, ivBase64, encryptedKey, version)); + } + if (!"1.0".equals(version)) { throw new InvalidLicenseException("Unexpected file version: " + version); } diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED index 0e888c7fac..8dd673e2d7 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED @@ -31,6 +31,8 @@ CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_title=License Number Alr 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 +# {0} - licenseCode +CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc=Error activating boost license {0} CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later. CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error # {0} - expiresDate diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java index 375943188c..735be72afc 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.java @@ -608,6 +608,8 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel { @NbBundle.Messages({ "CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error", "CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error", + "# {0} - licenseCode", + "CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc=Error activating boost license {0}", "CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.",}) private class LicenseFetcher extends SwingWorker { @@ -629,10 +631,9 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel { protected void done() { try { LicenseResponse licenseResponse = get(); - if (licenseResponse != null && licenseResponse.isSuccess()) { - SwingUtilities.invokeLater(() -> acceptEula(licenseResponse)); - } else { - logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch was not successful"); + // if no result, show unauthorized + if (licenseResponse == null) { + logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch returned no result."); JOptionPane.showMessageDialog( CTMalwareScannerOptionsPanel.this, CTCloudException.ErrorCode.UN_AUTHORIZED.getDescription(), @@ -640,7 +641,30 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel { JOptionPane.ERROR_MESSAGE); setLicenseDisplay(licenseInfo, null); loadMalwareScansInfo(licenseInfo); + return; } + + // if not successful response + if (!Boolean.TRUE.equals(licenseResponse.isSuccess())) { + logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch was not successful"); + // use default message unless error message specified + String message = Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc(licenseText); + if (!StringUtils.isBlank(licenseResponse.getErrorMsg())) { + message = licenseResponse.getErrorMsg(); + } + JOptionPane.showMessageDialog( + CTMalwareScannerOptionsPanel.this, + message, + Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title(), + JOptionPane.ERROR_MESSAGE); + setLicenseDisplay(licenseInfo, null); + loadMalwareScansInfo(licenseInfo); + return; + } + + // otherwise, load + SwingUtilities.invokeLater(() -> acceptEula(licenseResponse)); + } catch (InterruptedException | CancellationException ex) { // ignore cancellation; just load current license setLicenseDisplay(licenseInfo, null); From cfb619aaad83725fa8775fe9f166598e90027534 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 24 Aug 2023 17:15:30 -0400 Subject: [PATCH 4/8] add hint text --- .../ctoptions/ctcloud/Bundle.properties | 3 ++- .../ctoptions/ctcloud/Bundle.properties-MERGED | 5 +++-- .../ctoptions/ctcloud/CTLicenseDialog.form | 3 +++ .../ctoptions/ctcloud/CTLicenseDialog.java | 18 ++++++++++++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties index 3c86b5446d..44e71a4513 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties @@ -4,7 +4,7 @@ CTLicenseDialog.title=Add a License... CTLicenseDialog.licenseNumberLabel.text=License Number: -CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +CTLicenseDialog.licenseNumberTextField.text= CTLicenseDialog.cancelButton.text=Cancel CTLicenseDialog.okButton.text=Ok CTLicenseDialog.warningLabel.text= @@ -25,3 +25,4 @@ EULADialog.title=Cyber Triage End User License Agreement CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.disclaimer.text=The Cyber Triage Malware Scanner module uses 40+ malware scanning engines to identify if Windows executables are malicious. It requires a paid subscription to use. CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit +CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED index 8dd673e2d7..d9876a8ed7 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties-MERGED @@ -4,11 +4,11 @@ CTLicenseDialog.title=Add a License... CTLicenseDialog.licenseNumberLabel.text=License Number: -CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +CTLicenseDialog.licenseNumberTextField.text= CTLicenseDialog.cancelButton.text=Cancel CTLicenseDialog.okButton.text=Ok CTLicenseDialog.warningLabel.text= -CTLicenseDialog_verifyInput_licenseNumberError=Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' +CTLicenseDialog_verifyInput_licenseNumberError=Please enter a license number CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text= CTMalwareScannerOptionsPanel.countersResetLabel.text= CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text= @@ -65,3 +65,4 @@ EULADialog.title=Cyber Triage End User License Agreement CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.disclaimer.text=The Cyber Triage Malware Scanner module uses 40+ malware scanning engines to identify if Windows executables are malicious. It requires a paid subscription to use. CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit +CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.form b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.form index e7cd2743a0..2ea57d43a8 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.form +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.form @@ -127,6 +127,9 @@ + + + diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java index 3bff998901..495ee9d032 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java @@ -18,11 +18,13 @@ */ package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud; +import java.awt.Color; 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; +import org.sleuthkit.autopsy.corecomponents.TextPrompt; /** * License dialog @@ -38,6 +40,7 @@ class CTLicenseDialog extends javax.swing.JDialog { public CTLicenseDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); + configureHintText(); this.licenseNumberTextField.getDocument().putProperty("filterNewlines", Boolean.TRUE); this.licenseNumberTextField.getDocument().addDocumentListener(new DocumentListener() { @Override @@ -56,13 +59,23 @@ class CTLicenseDialog extends javax.swing.JDialog { } }); } - + + private void configureHintText() { + TextPrompt textPrompt = new TextPrompt( + StringUtils.defaultString(this.licenseNumberTextField.getToolTipText()), + this.licenseNumberTextField); + + textPrompt.setForeground(Color.LIGHT_GRAY); + float alpha = 0.9f; // Mostly opaque + textPrompt.changeAlpha(alpha); + } + String getValue() { return licenseString; } @Messages({ - "CTLicenseDialog_verifyInput_licenseNumberError=Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'" + "CTLicenseDialog_verifyInput_licenseNumberError=Please enter a license number" }) private void verifyInput() { String licenseInput = StringUtils.defaultString(this.licenseNumberTextField.getText()); @@ -165,6 +178,7 @@ class CTLicenseDialog extends javax.swing.JDialog { getContentPane().add(cancelButton, gridBagConstraints); licenseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.text")); // NOI18N + licenseNumberTextField.setToolTipText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.toolTipText")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; From 227d32d1c01b81ea34cc01c3f09de51f94c4de40 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 25 Aug 2023 07:56:29 -0400 Subject: [PATCH 5/8] better error message --- .../autopsy/ctapi/CTCloudHttpClient.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/CTCloudHttpClient.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/CTCloudHttpClient.java index 0a7c69cdee..cf93d58307 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/CTCloudHttpClient.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctapi/CTCloudHttpClient.java @@ -158,16 +158,23 @@ class CTCloudHttpClient { // Parse Response if (classType != null) { HttpEntity entity = response.getEntity(); - String entityStr = EntityUtils.toString(entity); - O respObj = mapper.readValue(entityStr, classType); - return respObj; - } else { - return null; + if (entity != null) { + String entityStr = EntityUtils.toString(entity); + if (StringUtils.isNotBlank(entityStr)) { + O respObj = mapper.readValue(entityStr, classType); + return respObj; + } + } } + + return null; } else { LOGGER.log(Level.WARNING, "Response Received. - Status Error {}", response.getStatusLine()); handleNonOKResponse(response, ""); } + // transform all non-CTCloudException's into a CTCloudException + } catch (CTCloudException ex) { + throw ex; } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error when parsing response from CyberTriage Cloud", ex); throw new CTCloudException(CTCloudException.parseUnknownException(ex), ex); @@ -191,7 +198,7 @@ class CTCloudHttpClient { if (fileUploadRequest == null) { throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fileUploadRequest cannot be null")); } - + String fullUrlPath = fileUploadRequest.getFullUrlPath(); String fileName = fileUploadRequest.getFileName(); InputStream fileInputStream = fileUploadRequest.getFileInputStream(); @@ -200,7 +207,7 @@ class CTCloudHttpClient { if (StringUtils.isBlank(fullUrlPath) || fileInputStream == null || contentLength == null || contentLength <= 0) { throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fullUrlPath, fileInputStream, contentLength must not be empty, null or less than 0")); } - + URI putUri; try { putUri = new URI(fullUrlPath); From 12fe1e961472488dc4c9c92c5c77d5ee2e6b57f2 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 25 Aug 2023 11:01:35 -0400 Subject: [PATCH 6/8] license code validation and trim --- .../autopsy/ctoptions/ctcloud/CTLicenseDialog.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java index 495ee9d032..99fc749dd7 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicenseDialog.java @@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.corecomponents.TextPrompt; */ class CTLicenseDialog extends javax.swing.JDialog { - private static final Pattern LICENSE_PATTERN = Pattern.compile("^\\s*[a-zA-Z0-9\\-]+?\\s*$"); + private static final Pattern LICENSE_PATTERN = Pattern.compile("^\\s*[a-zA-Z0-9-_]+?\\s*$"); private String licenseString = null; /** @@ -191,7 +191,8 @@ class CTLicenseDialog extends javax.swing.JDialog { }// //GEN-END:initComponents private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed - this.licenseString = this.licenseNumberTextField.getText(); + String inputText = this.licenseNumberTextField.getText(); + this.licenseString = inputText == null ? null : inputText.trim(); this.dispose(); }//GEN-LAST:event_okButtonActionPerformed From 518643d988ff05b683d669239eeaac777f25adb4 Mon Sep 17 00:00:00 2001 From: "eugene.livis" Date: Fri, 25 Aug 2023 15:59:27 -0400 Subject: [PATCH 7/8] Updated NBM and Autopsy version numbers --- Core/manifest.mf | 2 +- Core/nbproject/project.properties | 2 +- CoreLibs/manifest.mf | 2 +- Experimental/nbproject/project.xml | 4 ++-- ImageGallery/nbproject/project.xml | 2 +- KeywordSearch/manifest.mf | 2 +- KeywordSearch/nbproject/project.properties | 2 +- KeywordSearch/nbproject/project.xml | 2 +- RecentActivity/manifest.mf | 2 +- Testing/nbproject/project.xml | 4 ++-- nbproject/project.properties | 2 +- thunderbirdparser/nbproject/project.xml | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Core/manifest.mf b/Core/manifest.mf index 59baf3f8c2..683690ef1b 100644 --- a/Core/manifest.mf +++ b/Core/manifest.mf @@ -2,7 +2,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.core/10 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml -OpenIDE-Module-Implementation-Version: 37 +OpenIDE-Module-Implementation-Version: 38 OpenIDE-Module-Requires: org.openide.windows.WindowManager AutoUpdate-Show-In-Client: true AutoUpdate-Essential-Module: true diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 71acddc08a..893ff6510e 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -107,4 +107,4 @@ license.file=../LICENSE-2.0.txt nbm.homepage=http://www.sleuthkit.org/ nbm.module.author=Brian Carrier nbm.needs.restart=true -spec.version.base=10.24 +spec.version.base=10.25 diff --git a/CoreLibs/manifest.mf b/CoreLibs/manifest.mf index 1d3168bf2c..9f684569fe 100644 --- a/CoreLibs/manifest.mf +++ b/CoreLibs/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3 -OpenIDE-Module-Implementation-Version: 7 +OpenIDE-Module-Implementation-Version: 8 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties OpenIDE-Module-Specification-Version: 1.4 AutoUpdate-Show-In-Client: true diff --git a/Experimental/nbproject/project.xml b/Experimental/nbproject/project.xml index 7760187c5e..79af40a112 100644 --- a/Experimental/nbproject/project.xml +++ b/Experimental/nbproject/project.xml @@ -144,7 +144,7 @@ 10 - 10.24 + 10.25 @@ -162,7 +162,7 @@ 6 - 6.6 + 6.7 diff --git a/ImageGallery/nbproject/project.xml b/ImageGallery/nbproject/project.xml index 7a505d2ea6..d42fd1a08a 100644 --- a/ImageGallery/nbproject/project.xml +++ b/ImageGallery/nbproject/project.xml @@ -127,7 +127,7 @@ 10 - 10.24 + 10.25 diff --git a/KeywordSearch/manifest.mf b/KeywordSearch/manifest.mf index 0e947e073b..f4abb2b2b9 100644 --- a/KeywordSearch/manifest.mf +++ b/KeywordSearch/manifest.mf @@ -1,7 +1,7 @@ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/6 -OpenIDE-Module-Implementation-Version: 23 +OpenIDE-Module-Implementation-Version: 24 OpenIDE-Module-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index baa7a10c98..16289e9e73 100644 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -48,4 +48,4 @@ javac.compilerargs=-Xlint -Xlint:-serial license.file=../LICENSE-2.0.txt nbm.homepage=http://www.sleuthkit.org/autopsy/ nbm.needs.restart=true -spec.version.base=6.6 +spec.version.base=6.7 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index c1048f48ee..98a84faeb5 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -128,7 +128,7 @@ 10 - 10.24 + 10.25 diff --git a/RecentActivity/manifest.mf b/RecentActivity/manifest.mf index 03c6ce986b..6ab9cc4ccc 100644 --- a/RecentActivity/manifest.mf +++ b/RecentActivity/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.recentactivity/6 -OpenIDE-Module-Implementation-Version: 19 +OpenIDE-Module-Implementation-Version: 20 OpenIDE-Module-Layer: org/sleuthkit/autopsy/recentactivity/layer.xml OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties OpenIDE-Module-Requires: diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml index c27ee220ec..cee5e3ed5b 100644 --- a/Testing/nbproject/project.xml +++ b/Testing/nbproject/project.xml @@ -47,7 +47,7 @@ 10 - 10.24 + 10.25 @@ -73,7 +73,7 @@ 6 - 6.6 + 6.7 diff --git a/nbproject/project.properties b/nbproject/project.properties index e8d17eb3c8..d613ea09d4 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -4,7 +4,7 @@ app.title=Autopsy ### lowercase version of above app.name=${branding.token} ### if left unset, version will default to today's date -app.version=4.20.0 +app.version=4.21.0 ### build.type must be one of: DEVELOPMENT, RELEASE #build.type=RELEASE build.type=DEVELOPMENT diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml index 5c4fa0e042..abcccdc19c 100644 --- a/thunderbirdparser/nbproject/project.xml +++ b/thunderbirdparser/nbproject/project.xml @@ -54,7 +54,7 @@ 10 - 10.24 + 10.25 From fd74be8a11f14a55f41bafc8db52e0ff0391d1c8 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 25 Aug 2023 20:42:46 -0400 Subject: [PATCH 8/8] detect ct module --- .../autopsy/incidentoptions/Bundle.properties | 2 + .../incidentoptions/Bundle.properties-MERGED | 4 ++ .../CTIncidentImportOptionsPanel.form | 34 ++++++++++++-- .../CTIncidentImportOptionsPanel.java | 47 ++++++++++++++++++- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties index ebde860d0b..48a2628742 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties @@ -12,3 +12,5 @@ CTIncidentImportOptionsPanel.border.title_1=Incident Importer CTIncidentImportOptionsPanel.incidentTextLabel.text=The Cyber Triage Incident Import module allows you to open data collected by Cyber Triage in Autopsy. To use this feature you must install the Cyber Triage Import Module. CTincidentImportOptionsPanel.instructionsTextLabel.text= CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to: +CTIncidentImportOptionsPanel.importModule.text=Cyber Triage Import Module: +CTIncidentImportOptionsPanel.importModuleDetected.text= diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties-MERGED b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties-MERGED index ebde860d0b..dd406e6725 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties-MERGED +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties-MERGED @@ -12,3 +12,7 @@ CTIncidentImportOptionsPanel.border.title_1=Incident Importer CTIncidentImportOptionsPanel.incidentTextLabel.text=The Cyber Triage Incident Import module allows you to open data collected by Cyber Triage in Autopsy. To use this feature you must install the Cyber Triage Import Module. CTincidentImportOptionsPanel.instructionsTextLabel.text= CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to: +CTIncidentImportOptionsPanel.importModule.text=Cyber Triage Import Module: +CTIncidentImportOptionsPanel.importModuleDetected.text= +CTIncidentImportOptionsPanel_setModuleDetected_detected=Detected +CTIncidentImportOptionsPanel_setModuleDetected_notDetected=Not Detected diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form index 7382a2de2c..fd11f53ee8 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form @@ -42,7 +42,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,7 +96,7 @@ - + @@ -86,7 +114,7 @@ - + diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java index ef7aa5a67e..40a2c0fe3f 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java @@ -24,15 +24,20 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Collection; import java.util.Collections; import java.util.logging.Level; +import java.util.stream.Stream; import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.JFileChooser; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.apache.commons.lang3.StringUtils; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.Lookup; +import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.AutopsyContentProvider; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.guiutils.JFileChooserFactory; @@ -46,6 +51,8 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { private static final String CT_IMPORTER_DOC_LINK = "https://docs.cybertriage.com/en/latest/chapters/integrations/autopsy.html"; + private static final String CT_STANDARD_CONTENT_PROVIDER_NAME = "CTStandardContentProvider"; + private final JFileChooserFactory fileRepoChooserFactory = new JFileChooserFactory(); private final CTSettingsPersistence ctPersistence = CTSettingsPersistence.getInstance(); @@ -93,8 +100,23 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { public synchronized void loadSettings() { CTSettings ctSettings = ctPersistence.loadCTSettings(); setCTSettingsDisplay(ctSettings); + setModuleDetected(); setEnabledItems(Case.isCaseOpen()); } + + @Messages({ + "CTIncidentImportOptionsPanel_setModuleDetected_detected=Detected", + "CTIncidentImportOptionsPanel_setModuleDetected_notDetected=Not Detected" + }) + private void setModuleDetected() { + Collection contentProviders = Lookup.getDefault().lookupAll(AutopsyContentProvider.class); + boolean detected = ((Collection) (contentProviders != null ? contentProviders : Collections.emptyList())).stream() + .anyMatch(p -> p != null && StringUtils.defaultString(p.getName()).toUpperCase().startsWith(CT_STANDARD_CONTENT_PROVIDER_NAME.toUpperCase())); + + this.importModuleDetected.setText(detected + ? Bundle.CTIncidentImportOptionsPanel_setModuleDetected_detected() + : Bundle.CTIncidentImportOptionsPanel_setModuleDetected_notDetected()); + } private void setEnabledItems(boolean caseOpen) { this.caseOpenWarningLabel.setVisible(caseOpen); @@ -127,6 +149,8 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { incidentTextPanel = new javax.swing.JPanel(); incidentTextLabel = new javax.swing.JLabel(); + javax.swing.JLabel importModule = new javax.swing.JLabel(); + importModuleDetected = new javax.swing.JLabel(); instructionsPanel = new javax.swing.JPanel(); instructionsTextLabel = new javax.swing.JLabel(); instructionsLinkLabel = new javax.swing.JLabel(); @@ -145,10 +169,28 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); incidentTextPanel.add(incidentTextLabel, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(importModule, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.importModule.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 3); + incidentTextPanel.add(importModule, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(importModuleDetected, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.importModuleDetected.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, 0, 5, 5); + incidentTextPanel.add(importModuleDetected, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; @@ -161,7 +203,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0); instructionsPanel.add(instructionsTextLabel, gridBagConstraints); instructionsTextLabel.getAccessibleContext().setAccessibleName("For instructions on obtaining the module refer to:"); @@ -176,7 +218,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); instructionsPanel.add(instructionsLinkLabel, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); @@ -283,6 +325,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { private javax.swing.JLabel caseOpenWarningLabel; private javax.swing.JButton fileRepoBrowseButton; private javax.swing.JTextField fileRepoPathField; + private javax.swing.JLabel importModuleDetected; private javax.swing.JLabel incidentTextLabel; private javax.swing.JPanel incidentTextPanel; private javax.swing.JLabel instructionsLinkLabel;