Merge branch 'release-4.21.0' of github.com:sleuthkit/autopsy into graphicsEnvHeadless

This commit is contained in:
Greg DiCristofaro 2023-08-30 08:20:39 -04:00
commit 842d1fb856
30 changed files with 296 additions and 140 deletions

View File

@ -2,7 +2,7 @@ Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.core/10 OpenIDE-Module: org.sleuthkit.autopsy.core/10
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml 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 OpenIDE-Module-Requires: org.openide.windows.WindowManager
AutoUpdate-Show-In-Client: true AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true AutoUpdate-Essential-Module: true

View File

@ -107,4 +107,4 @@ license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/ nbm.homepage=http://www.sleuthkit.org/
nbm.module.author=Brian Carrier nbm.module.author=Brian Carrier
nbm.needs.restart=true nbm.needs.restart=true
spec.version.base=10.24 spec.version.base=10.25

View File

@ -158,16 +158,23 @@ class CTCloudHttpClient {
// Parse Response // Parse Response
if (classType != null) { if (classType != null) {
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
String entityStr = EntityUtils.toString(entity); if (entity != null) {
O respObj = mapper.readValue(entityStr, classType); String entityStr = EntityUtils.toString(entity);
return respObj; if (StringUtils.isNotBlank(entityStr)) {
} else { O respObj = mapper.readValue(entityStr, classType);
return null; return respObj;
}
}
} }
return null;
} else { } else {
LOGGER.log(Level.WARNING, "Response Received. - Status Error {}", response.getStatusLine()); LOGGER.log(Level.WARNING, "Response Received. - Status Error {}", response.getStatusLine());
handleNonOKResponse(response, ""); handleNonOKResponse(response, "");
} }
// transform all non-CTCloudException's into a CTCloudException
} catch (CTCloudException ex) {
throw ex;
} catch (Exception ex) { } catch (Exception ex) {
LOGGER.log(Level.WARNING, "Error when parsing response from CyberTriage Cloud", ex); LOGGER.log(Level.WARNING, "Error when parsing response from CyberTriage Cloud", ex);
throw new CTCloudException(CTCloudException.parseUnknownException(ex), ex); throw new CTCloudException(CTCloudException.parseUnknownException(ex), ex);
@ -191,7 +198,7 @@ class CTCloudHttpClient {
if (fileUploadRequest == null) { if (fileUploadRequest == null) {
throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fileUploadRequest cannot be null")); throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fileUploadRequest cannot be null"));
} }
String fullUrlPath = fileUploadRequest.getFullUrlPath(); String fullUrlPath = fileUploadRequest.getFullUrlPath();
String fileName = fileUploadRequest.getFileName(); String fileName = fileUploadRequest.getFileName();
InputStream fileInputStream = fileUploadRequest.getFileInputStream(); InputStream fileInputStream = fileUploadRequest.getFileInputStream();
@ -200,7 +207,7 @@ class CTCloudHttpClient {
if (StringUtils.isBlank(fullUrlPath) || fileInputStream == null || contentLength == null || contentLength <= 0) { 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")); throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fullUrlPath, fileInputStream, contentLength must not be empty, null or less than 0"));
} }
URI putUri; URI putUri;
try { try {
putUri = new URI(fullUrlPath); putUri = new URI(fullUrlPath);

View File

@ -32,18 +32,21 @@ public class LicenseResponse {
private final Boolean hostChanged; private final Boolean hostChanged;
private final Long hostChangesRemaining; private final Long hostChangesRemaining;
private final BoostLicenseResponse boostLicense; private final BoostLicenseResponse boostLicense;
private final String errorMsg;
@JsonCreator @JsonCreator
public LicenseResponse( public LicenseResponse(
@JsonProperty("success") Boolean success, @JsonProperty("success") Boolean success,
@JsonProperty("hostChanged") Boolean hostChanged, @JsonProperty("hostChanged") Boolean hostChanged,
@JsonProperty("hostChangesRemaining") Long hostChangesRemaining, @JsonProperty("hostChangesRemaining") Long hostChangesRemaining,
@JsonProperty("boostLicense") BoostLicenseResponse boostLicense @JsonProperty("boostLicense") BoostLicenseResponse boostLicense,
@JsonProperty("errorMsg") String errorMsg
) { ) {
this.success = success; this.success = success;
this.hostChanged = hostChanged; this.hostChanged = hostChanged;
this.hostChangesRemaining = hostChangesRemaining; this.hostChangesRemaining = hostChangesRemaining;
this.boostLicense = boostLicense; this.boostLicense = boostLicense;
this.errorMsg = errorMsg;
} }
public Boolean isSuccess() { public Boolean isSuccess() {
@ -61,4 +64,8 @@ public class LicenseResponse {
public BoostLicenseResponse getBoostLicense() { public BoostLicenseResponse getBoostLicense() {
return boostLicense; return boostLicense;
} }
public String getErrorMsg() {
return errorMsg;
}
} }

View File

@ -34,6 +34,7 @@ import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.text.MessageFormat;
import java.util.Base64; import java.util.Base64;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -42,6 +43,7 @@ import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.ObjectUtils;
/** /**
* Decrypts the payload of boost license. * Decrypts the payload of boost license.
@ -58,12 +60,12 @@ public class LicenseDecryptorUtil {
private LicenseDecryptorUtil() { private LicenseDecryptorUtil() {
} }
public LicenseInfo createLicenseInfo(LicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException { public LicenseInfo createLicenseInfo(LicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
if (licenseResponse == null || licenseResponse.getBoostLicense() == null) { if (licenseResponse == null) {
throw new InvalidLicenseException("License or boost license are null"); throw new InvalidLicenseException("License is null");
} }
DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense()); DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense());
return new LicenseInfo(licenseResponse, decrypted); return new LicenseInfo(licenseResponse, decrypted);
} }
@ -78,6 +80,9 @@ public class LicenseDecryptorUtil {
* com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException * com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException
*/ */
public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException { public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
if (licenseResponse == null) {
throw new InvalidLicenseException("Boost license is null");
}
String decryptedJsonResponse; String decryptedJsonResponse;
try { try {
@ -101,6 +106,12 @@ public class LicenseDecryptorUtil {
} }
private String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version) throws IOException, GeneralSecurityException, InvalidLicenseException { 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)) { if (!"1.0".equals(version)) {
throw new InvalidLicenseException("Unexpected file version: " + version); throw new InvalidLicenseException("Unexpected file version: " + version);
} }

View File

@ -26,12 +26,12 @@ import java.beans.PropertyChangeListener;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.netbeans.spi.options.OptionsPanelController; import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
/** /**

View File

@ -4,7 +4,7 @@
CTLicenseDialog.title=Add a License... CTLicenseDialog.title=Add a License...
CTLicenseDialog.licenseNumberLabel.text=License Number: CTLicenseDialog.licenseNumberLabel.text=License Number:
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX CTLicenseDialog.licenseNumberTextField.text=
CTLicenseDialog.cancelButton.text=Cancel CTLicenseDialog.cancelButton.text=Cancel
CTLicenseDialog.okButton.text=Ok CTLicenseDialog.okButton.text=Ok
CTLicenseDialog.warningLabel.text= CTLicenseDialog.warningLabel.text=
@ -25,3 +25,4 @@ EULADialog.title=Cyber Triage End User License Agreement
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
CTMalwareScannerOptionsPanel.disclaimer.text=<html>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.</html> CTMalwareScannerOptionsPanel.disclaimer.text=<html>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.</html>
CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit
CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

View File

@ -4,11 +4,11 @@
CTLicenseDialog.title=Add a License... CTLicenseDialog.title=Add a License...
CTLicenseDialog.licenseNumberLabel.text=License Number: CTLicenseDialog.licenseNumberLabel.text=License Number:
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX CTLicenseDialog.licenseNumberTextField.text=
CTLicenseDialog.cancelButton.text=Cancel CTLicenseDialog.cancelButton.text=Cancel
CTLicenseDialog.okButton.text=Ok CTLicenseDialog.okButton.text=Ok
CTLicenseDialog.warningLabel.text= CTLicenseDialog.warningLabel.text=
CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html> CTLicenseDialog_verifyInput_licenseNumberError=<html>Please enter a license number</html>
CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text= CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text=
CTMalwareScannerOptionsPanel.countersResetLabel.text= CTMalwareScannerOptionsPanel.countersResetLabel.text=
CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text= CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text=
@ -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_desc=Please verify that license number is of format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_title=Invalid License Number CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_title=Invalid License Number
CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error 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_desc=A general error occurred while fetching license information. Please try again later.
CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error
# {0} - expiresDate # {0} - expiresDate
@ -63,3 +65,4 @@ EULADialog.title=Cyber Triage End User License Agreement
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
CTMalwareScannerOptionsPanel.disclaimer.text=<html>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.</html> CTMalwareScannerOptionsPanel.disclaimer.text=<html>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.</html>
CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit
CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

View File

@ -127,6 +127,9 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <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, &quot;{key}&quot;)"/> <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.licenseNumberTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="toolTipText" 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.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">

View File

@ -18,18 +18,20 @@
*/ */
package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud; package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud;
import java.awt.Color;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.corecomponents.TextPrompt;
/** /**
* License dialog * License dialog
*/ */
class CTLicenseDialog extends javax.swing.JDialog { 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; private String licenseString = null;
/** /**
@ -38,6 +40,7 @@ class CTLicenseDialog extends javax.swing.JDialog {
public CTLicenseDialog(java.awt.Frame parent, boolean modal) { public CTLicenseDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal); super(parent, modal);
initComponents(); initComponents();
configureHintText();
this.licenseNumberTextField.getDocument().putProperty("filterNewlines", Boolean.TRUE); this.licenseNumberTextField.getDocument().putProperty("filterNewlines", Boolean.TRUE);
this.licenseNumberTextField.getDocument().addDocumentListener(new DocumentListener() { this.licenseNumberTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override @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() { String getValue() {
return licenseString; return licenseString;
} }
@Messages({ @Messages({
"CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html>" "CTLicenseDialog_verifyInput_licenseNumberError=<html>Please enter a license number</html>"
}) })
private void verifyInput() { private void verifyInput() {
String licenseInput = StringUtils.defaultString(this.licenseNumberTextField.getText()); String licenseInput = StringUtils.defaultString(this.licenseNumberTextField.getText());
@ -165,6 +178,7 @@ class CTLicenseDialog extends javax.swing.JDialog {
getContentPane().add(cancelButton, gridBagConstraints); getContentPane().add(cancelButton, gridBagConstraints);
licenseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.text")); // NOI18N 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 = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1; gridBagConstraints.gridy = 1;
@ -177,7 +191,8 @@ class CTLicenseDialog extends javax.swing.JDialog {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed 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(); this.dispose();
}//GEN-LAST:event_okButtonActionPerformed }//GEN-LAST:event_okButtonActionPerformed

View File

@ -40,7 +40,6 @@ import java.util.Optional;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
@ -51,6 +50,7 @@ import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* Options panel to be displayed in the CTOptionsPanel for settings regarding * Options panel to be displayed in the CTOptionsPanel for settings regarding
@ -608,6 +608,8 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
@NbBundle.Messages({ @NbBundle.Messages({
"CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error", "CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error",
"CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General 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.",}) "CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.",})
private class LicenseFetcher extends SwingWorker<LicenseResponse, Void> { private class LicenseFetcher extends SwingWorker<LicenseResponse, Void> {
@ -629,10 +631,9 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
protected void done() { protected void done() {
try { try {
LicenseResponse licenseResponse = get(); LicenseResponse licenseResponse = get();
if (licenseResponse != null && licenseResponse.isSuccess()) { // if no result, show unauthorized
SwingUtilities.invokeLater(() -> acceptEula(licenseResponse)); if (licenseResponse == null) {
} else { logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch returned no result.");
logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch was not successful");
JOptionPane.showMessageDialog( JOptionPane.showMessageDialog(
CTMalwareScannerOptionsPanel.this, CTMalwareScannerOptionsPanel.this,
CTCloudException.ErrorCode.UN_AUTHORIZED.getDescription(), CTCloudException.ErrorCode.UN_AUTHORIZED.getDescription(),
@ -640,7 +641,30 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
setLicenseDisplay(licenseInfo, null); setLicenseDisplay(licenseInfo, null);
loadMalwareScansInfo(licenseInfo); 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) { } catch (InterruptedException | CancellationException ex) {
// ignore cancellation; just load current license // ignore cancellation; just load current license
setLicenseDisplay(licenseInfo, null); setLicenseDisplay(licenseInfo, null);

View File

@ -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.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=
CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to: CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to:
CTIncidentImportOptionsPanel.importModule.text=Cyber Triage Import Module:
CTIncidentImportOptionsPanel.importModuleDetected.text=

View File

@ -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.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=
CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to: 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

View File

@ -42,7 +42,35 @@
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/> <GridBagConstraints gridX="0" gridY="0" gridWidth="2" 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="importModule">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties" key="CTIncidentImportOptionsPanel.importModule.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</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="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="3" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="importModuleDetected">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties" key="CTIncidentImportOptionsPanel.importModuleDetected.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</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="0" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
@ -68,7 +96,7 @@
</AccessibilityProperties> </AccessibilityProperties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
@ -86,7 +114,7 @@
</Events> </Events>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="0" 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"/> <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>

View File

@ -1,16 +1,21 @@
/** ************************************************************************* /*
** This data and information is proprietary to, and a valuable trade secret * Autopsy Forensic Browser
** 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 * Copyright 2023 Basis Technology Corp.
** it has been distributed, and in no other way. * Contact: carrier <at> sleuthkit <dot> org
** *
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved * Licensed under the Apache License, Version 2.0 (the "License");
** * you may not use this file except in compliance with the License.
** The technical data and information provided herein are provided with * You may obtain a copy of the License at
** `limited rights', and the computer software provided herein is provided *
** with `restricted rights' as those terms are defined in DAR and ASPR * http://www.apache.org/licenses/LICENSE-2.0
** 7-104.9(a). *
************************************************************************** */ * 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; package com.basistech.df.cybertriage.autopsy.incidentoptions;
import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel; import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel;
@ -19,15 +24,20 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.stream.Stream;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.netbeans.spi.options.OptionsPanelController; 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.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.AutopsyContentProvider;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory; import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
@ -41,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_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 JFileChooserFactory fileRepoChooserFactory = new JFileChooserFactory();
private final CTSettingsPersistence ctPersistence = CTSettingsPersistence.getInstance(); private final CTSettingsPersistence ctPersistence = CTSettingsPersistence.getInstance();
@ -88,8 +100,23 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
public synchronized void loadSettings() { public synchronized void loadSettings() {
CTSettings ctSettings = ctPersistence.loadCTSettings(); CTSettings ctSettings = ctPersistence.loadCTSettings();
setCTSettingsDisplay(ctSettings); setCTSettingsDisplay(ctSettings);
setModuleDetected();
setEnabledItems(Case.isCaseOpen()); setEnabledItems(Case.isCaseOpen());
} }
@Messages({
"CTIncidentImportOptionsPanel_setModuleDetected_detected=Detected",
"CTIncidentImportOptionsPanel_setModuleDetected_notDetected=Not Detected"
})
private void setModuleDetected() {
Collection<? extends AutopsyContentProvider> contentProviders = Lookup.getDefault().lookupAll(AutopsyContentProvider.class);
boolean detected = ((Collection<? extends AutopsyContentProvider>) (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) { private void setEnabledItems(boolean caseOpen) {
this.caseOpenWarningLabel.setVisible(caseOpen); this.caseOpenWarningLabel.setVisible(caseOpen);
@ -122,6 +149,8 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
incidentTextPanel = new javax.swing.JPanel(); incidentTextPanel = new javax.swing.JPanel();
incidentTextLabel = new javax.swing.JLabel(); incidentTextLabel = new javax.swing.JLabel();
javax.swing.JLabel importModule = new javax.swing.JLabel();
importModuleDetected = new javax.swing.JLabel();
instructionsPanel = new javax.swing.JPanel(); instructionsPanel = new javax.swing.JPanel();
instructionsTextLabel = new javax.swing.JLabel(); instructionsTextLabel = new javax.swing.JLabel();
instructionsLinkLabel = new javax.swing.JLabel(); instructionsLinkLabel = new javax.swing.JLabel();
@ -140,10 +169,28 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
incidentTextPanel.add(incidentTextLabel, gridBagConstraints); 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 = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
@ -156,7 +203,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 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); instructionsPanel.add(instructionsTextLabel, gridBagConstraints);
instructionsTextLabel.getAccessibleContext().setAccessibleName("For instructions on obtaining the module refer to:"); instructionsTextLabel.getAccessibleContext().setAccessibleName("For instructions on obtaining the module refer to:");
@ -171,7 +218,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
gridBagConstraints.gridx = 1; gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 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); instructionsPanel.add(instructionsLinkLabel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
@ -278,6 +325,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
private javax.swing.JLabel caseOpenWarningLabel; private javax.swing.JLabel caseOpenWarningLabel;
private javax.swing.JButton fileRepoBrowseButton; private javax.swing.JButton fileRepoBrowseButton;
private javax.swing.JTextField fileRepoPathField; private javax.swing.JTextField fileRepoPathField;
private javax.swing.JLabel importModuleDetected;
private javax.swing.JLabel incidentTextLabel; private javax.swing.JLabel incidentTextLabel;
private javax.swing.JPanel incidentTextPanel; private javax.swing.JPanel incidentTextPanel;
private javax.swing.JLabel instructionsLinkLabel; private javax.swing.JLabel instructionsLinkLabel;

View File

@ -1,16 +1,21 @@
/** ************************************************************************* /*
** This data and information is proprietary to, and a valuable trade secret * Autopsy Forensic Browser
** 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 * Copyright 2023 Basis Technology Corp.
** it has been distributed, and in no other way. * Contact: carrier <at> sleuthkit <dot> org
** *
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved * Licensed under the Apache License, Version 2.0 (the "License");
** * you may not use this file except in compliance with the License.
** The technical data and information provided herein are provided with * You may obtain a copy of the License at
** `limited rights', and the computer software provided herein is provided *
** with `restricted rights' as those terms are defined in DAR and ASPR * http://www.apache.org/licenses/LICENSE-2.0
** 7-104.9(a). *
************************************************************************** */ * 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; package com.basistech.df.cybertriage.autopsy.incidentoptions;
import java.io.IOException; import java.io.IOException;
@ -19,35 +24,60 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import java.util.logging.Level; 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.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 settings that don't include license information. This code must be kept
* CT Autopsy Importer NBM. * in-sync with code in CT Autopsy Importer NBM.
*/ */
public class CTSettings { public class CTSettings {
private static final Logger LOGGER = Logger.getLogger(CTSettings.class.getCanonicalName());
private static final String DEFAULT_FILE_REPO_PATH = getAppDataLocalDirectory(); private static final String DEFAULT_FILE_REPO_PATH = getAppDataLocalDirectory();
// taken from com.basistech.df.cybertriage.utils.SystemProperties private static final String CYBERTRIAGE_FOLDER = "cybertriage";
private static String getAppDataLocalDirectory() { 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 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()); LOGGER.log(Level.INFO, "Application Data (test mode) Path: " + Places.getUserDirectory().getAbsolutePath());
return Places.getUserDirectory().getAbsolutePath(); return Places.getUserDirectory().getAbsolutePath();
} else { }
Path localAppPath = 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 { try {
Files.createDirectories(localAppPath); Files.createDirectories(localAppPath);
LOGGER.log(Level.INFO, "Application Data Path: " + localAppPath.toString()); LOGGER.log(Level.INFO, "Application Data Path: " + localAppPath.toString());
return localAppPath.toString(); return localAppPath.toString();
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.log(Level.SEVERE, "IO Error, defaulting to user dir", ex); LOGGER.log(Level.SEVERE, "IO Error using " + localAppPath.toString(), ex);
return Places.getUserDirectory().getAbsolutePath(); // In case of an IO Error
} }
} }
// 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() { public static String getDefaultFileRepoPath() {

View File

@ -1,16 +1,21 @@
/** ************************************************************************* /*
** This data and information is proprietary to, and a valuable trade secret * Autopsy Forensic Browser
** 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 * Copyright 2023 Basis Technology Corp.
** it has been distributed, and in no other way. * Contact: carrier <at> sleuthkit <dot> org
** *
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved * Licensed under the Apache License, Version 2.0 (the "License");
** * you may not use this file except in compliance with the License.
** The technical data and information provided herein are provided with * You may obtain a copy of the License at
** `limited rights', and the computer software provided herein is provided *
** with `restricted rights' as those terms are defined in DAR and ASPR * http://www.apache.org/licenses/LICENSE-2.0
** 7-104.9(a). *
************************************************************************** */ * 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; package com.basistech.df.cybertriage.autopsy.incidentoptions;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;

View File

@ -134,8 +134,7 @@ class MalwareScanIngestModule implements FileIngestModule {
"application/x-msdos-program"//NON-NLS "application/x-msdos-program"//NON-NLS
).collect(Collectors.toSet()); ).collect(Collectors.toSet());
private static final String MALWARE_TYPE_NAME = "TSK_MALWARE"; private static final String MALWARE_CONFIG = ""; // NOTE: Adding a configuration complicates NTL branch UI
private static final String MALWARE_CONFIG = "Cyber Triage Cloud";
private static final Logger logger = Logger.getLogger(MalwareScanIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(MalwareScanIngestModule.class.getName());
@ -235,18 +234,13 @@ class MalwareScanIngestModule implements FileIngestModule {
// setup necessary variables for processing // setup necessary variables for processing
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
BlackboardArtifact.Type malwareType = tskCase.getBlackboard().getOrAddArtifactType(
MALWARE_TYPE_NAME,
Bundle.MalwareScanIngestModule_malwareTypeDisplayName(),
BlackboardArtifact.Category.ANALYSIS_RESULT);
return new IngestJobState( return new IngestJobState(
context, context,
tskCase, tskCase,
new PathNormalizer(tskCase), new PathNormalizer(tskCase),
new FileTypeDetector(), new FileTypeDetector(),
licenseInfoOpt.get(), licenseInfoOpt.get(),
malwareType, BlackboardArtifact.Type.TSK_MALWARE,
uploadFiles, uploadFiles,
true true
); );

View File

@ -64,6 +64,7 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_INTERESTING_IT
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_TL_EVENT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_TL_EVENT;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ASSOCIATED_OBJECT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ASSOCIATED_OBJECT;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_KEYWORD_HIT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_KEYWORD_HIT;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_MALWARE;
/** /**
* Classes for creating nodes for BlackboardArtifacts. * Classes for creating nodes for BlackboardArtifacts.
@ -73,10 +74,6 @@ public class Artifacts {
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST
= EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED); = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
// this is currently a custom TSK artifact type, created in MalwareScanIngestModule
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
private static final String MALWARE_HITS = "TSK_MALWARE";
/** /**
* Base class for a parent node of artifacts. * Base class for a parent node of artifacts.
*/ */
@ -247,15 +244,6 @@ public class Artifacts {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private static TypeNodeKey getTypeKey(BlackboardArtifact.Type type, SleuthkitCase skCase, long dsObjId) { private static TypeNodeKey getTypeKey(BlackboardArtifact.Type type, SleuthkitCase skCase, long dsObjId) {
// Get the custom TSK_MALWARE artifact type from case database
if (MALWARE_ARTIFACT_TYPE == null) {
try {
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
}
}
int typeId = type.getTypeID(); int typeId = type.getTypeID();
if (TSK_EMAIL_MSG.getTypeID() == typeId) { if (TSK_EMAIL_MSG.getTypeID() == typeId) {
EmailExtracted.RootNode emailNode = new EmailExtracted(skCase, dsObjId).new RootNode(); EmailExtracted.RootNode emailNode = new EmailExtracted(skCase, dsObjId).new RootNode();
@ -281,9 +269,9 @@ public class Artifacts {
} else if (TSK_HASHSET_HIT.getTypeID() == typeId) { } else if (TSK_HASHSET_HIT.getTypeID() == typeId) {
HashsetHits.RootNode hashsetHits = new HashsetHits(skCase, dsObjId).new RootNode(); HashsetHits.RootNode hashsetHits = new HashsetHits(skCase, dsObjId).new RootNode();
return new TypeNodeKey(hashsetHits, TSK_HASHSET_HIT); return new TypeNodeKey(hashsetHits, TSK_HASHSET_HIT);
} else if (MALWARE_ARTIFACT_TYPE != null && MALWARE_ARTIFACT_TYPE.getTypeID() == typeId) { } else if (TSK_MALWARE.getTypeID() == typeId) {
MalwareHits.RootNode malwareHits = new MalwareHits(skCase, dsObjId).new RootNode(); MalwareHits.RootNode malwareHits = new MalwareHits(skCase, dsObjId).new RootNode();
return new TypeNodeKey(malwareHits, MALWARE_ARTIFACT_TYPE); return new TypeNodeKey(malwareHits, TSK_MALWARE);
} else { } else {
return new TypeNodeKey(type, dsObjId); return new TypeNodeKey(type, dsObjId);
} }

View File

@ -44,12 +44,12 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode; import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.AnalysisResult;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_MALWARE;
import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.Score;
/** /**
@ -57,9 +57,6 @@ import org.sleuthkit.datamodel.Score;
*/ */
public class MalwareHits implements AutopsyVisitableItem { public class MalwareHits implements AutopsyVisitableItem {
private static final String MALWARE_HITS = "TSK_MALWARE"; // this is currently a custom TSK artifact type, created in MalwareScanIngestModule
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
private static String DISPLAY_NAME;
private static final Logger logger = Logger.getLogger(MalwareHits.class.getName()); private static final Logger logger = Logger.getLogger(MalwareHits.class.getName());
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED); private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED); private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
@ -126,20 +123,9 @@ public class MalwareHits implements AutopsyVisitableItem {
return; return;
} }
// Get the custom TSK_MALWARE artifact type from case database
if (MALWARE_ARTIFACT_TYPE == null) {
try {
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
DISPLAY_NAME = MALWARE_ARTIFACT_TYPE.getDisplayName();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
return;
}
}
String query = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS String query = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS
+ "FROM blackboard_artifacts,tsk_analysis_results WHERE " //NON-NLS + "FROM blackboard_artifacts,tsk_analysis_results WHERE " //NON-NLS
+ "blackboard_artifacts.artifact_type_id=" + MALWARE_ARTIFACT_TYPE.getTypeID() //NON-NLS + "blackboard_artifacts.artifact_type_id=" + TSK_MALWARE.getTypeID() //NON-NLS
+ " AND tsk_analysis_results.artifact_obj_id=blackboard_artifacts.artifact_obj_id" //NON-NLS + " AND tsk_analysis_results.artifact_obj_id=blackboard_artifacts.artifact_obj_id" //NON-NLS
+ " AND (tsk_analysis_results.significance=" + Score.Significance.NOTABLE.getId() //NON-NLS + " AND (tsk_analysis_results.significance=" + Score.Significance.NOTABLE.getId() //NON-NLS
+ " OR tsk_analysis_results.significance=" + Score.Significance.LIKELY_NOTABLE.getId() + " )"; //NON-NLS + " OR tsk_analysis_results.significance=" + Score.Significance.LIKELY_NOTABLE.getId() + " )"; //NON-NLS
@ -182,7 +168,7 @@ public class MalwareHits implements AutopsyVisitableItem {
* oldValue if the event is a remote event. * oldValue if the event is a remote event.
*/ */
ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue();
if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == MALWARE_ARTIFACT_TYPE.getTypeID()) { if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == TSK_MALWARE.getTypeID()) {
malwareResults.update(); malwareResults.update();
} }
} catch (NoCurrentCaseException notUsed) { } catch (NoCurrentCaseException notUsed) {
@ -248,13 +234,13 @@ public class MalwareHits implements AutopsyVisitableItem {
public class RootNode extends UpdatableCountTypeNode { public class RootNode extends UpdatableCountTypeNode {
public RootNode() { public RootNode() {
super(Children.create(new HitFactory(DISPLAY_NAME), true), super(Children.create(new HitFactory(TSK_MALWARE.getDisplayName()), true),
Lookups.singleton(DISPLAY_NAME), Lookups.singleton(TSK_MALWARE.getDisplayName()),
DISPLAY_NAME, TSK_MALWARE.getDisplayName(),
filteringDSObjId, filteringDSObjId,
MALWARE_ARTIFACT_TYPE); TSK_MALWARE);
super.setName(MALWARE_HITS); super.setName(TSK_MALWARE.getTypeName());
// TODO make an icon // TODO make an icon
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/artifact-icon.png"); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/artifact-icon.png");
} }
@ -297,7 +283,7 @@ public class MalwareHits implements AutopsyVisitableItem {
*/ */
@Override @Override
void updateDisplayName() { void updateDisplayName() {
super.setDisplayName(DISPLAY_NAME + " (" + malwareResults.getArtifactIds().size() + ")"); super.setDisplayName(TSK_MALWARE.getDisplayName() + " (" + malwareResults.getArtifactIds().size() + ")");
} }
} }

View File

@ -1,6 +1,6 @@
Manifest-Version: 1.0 Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3 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-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties
OpenIDE-Module-Specification-Version: 1.4 OpenIDE-Module-Specification-Version: 1.4
AutoUpdate-Show-In-Client: true AutoUpdate-Show-In-Client: true

View File

@ -144,7 +144,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>10</release-version> <release-version>10</release-version>
<specification-version>10.24</specification-version> <specification-version>10.25</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>
@ -162,7 +162,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>6</release-version> <release-version>6</release-version>
<specification-version>6.6</specification-version> <specification-version>6.7</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
</module-dependencies> </module-dependencies>

View File

@ -127,7 +127,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>10</release-version> <release-version>10</release-version>
<specification-version>10.24</specification-version> <specification-version>10.25</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,7 +1,7 @@
Manifest-Version: 1.0 Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true AutoUpdate-Show-In-Client: true
OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/6 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-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class
OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties

View File

@ -48,4 +48,4 @@ javac.compilerargs=-Xlint -Xlint:-serial
license.file=../LICENSE-2.0.txt license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/autopsy/ nbm.homepage=http://www.sleuthkit.org/autopsy/
nbm.needs.restart=true nbm.needs.restart=true
spec.version.base=6.6 spec.version.base=6.7

View File

@ -128,7 +128,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>10</release-version> <release-version>10</release-version>
<specification-version>10.24</specification-version> <specification-version>10.25</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,6 +1,6 @@
Manifest-Version: 1.0 Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.recentactivity/6 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-Layer: org/sleuthkit/autopsy/recentactivity/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties
OpenIDE-Module-Requires: OpenIDE-Module-Requires:

View File

@ -47,7 +47,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>10</release-version> <release-version>10</release-version>
<specification-version>10.24</specification-version> <specification-version>10.25</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>
@ -73,7 +73,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>6</release-version> <release-version>6</release-version>
<specification-version>6.6</specification-version> <specification-version>6.7</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
</module-dependencies> </module-dependencies>

View File

@ -4,7 +4,7 @@ app.title=Autopsy
### lowercase version of above ### lowercase version of above
app.name=${branding.token} app.name=${branding.token}
### if left unset, version will default to today's date ### 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 must be one of: DEVELOPMENT, RELEASE
#build.type=RELEASE #build.type=RELEASE
build.type=DEVELOPMENT build.type=DEVELOPMENT

View File

@ -54,7 +54,7 @@
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<release-version>10</release-version> <release-version>10</release-version>
<specification-version>10.24</specification-version> <specification-version>10.25</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>