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 745aa1d03db8ef43b393d2659f8d9aad4c6edb1f..83a4a9a51a3709bea181021c7881fb3a7254c39c 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/CTOptionsPanel.java @@ -64,12 +64,12 @@ public CTOptionsPanel() { } }) .filter(item -> item != null) - .sorted(Comparator.comparing(p -> p.getClass().getSimpleName().toUpperCase())) + .sorted(Comparator.comparing(p -> p.getClass().getSimpleName().toUpperCase()).reversed()) .collect(Collectors.toList()); - addSubOptionsPanels(new LicenseDisclaimerPanel(), this.subPanels); + addSubOptionsPanels(this.subPanels); } - private void addSubOptionsPanels(JPanel disclaimerPanel, List<CTOptionsSubPanel> subPanels) { + private void addSubOptionsPanels(List<CTOptionsSubPanel> subPanels) { GridBagConstraints disclaimerConstraints = new GridBagConstraints(); disclaimerConstraints.gridx = 0; disclaimerConstraints.gridy = 0; @@ -79,8 +79,6 @@ private void addSubOptionsPanels(JPanel disclaimerPanel, List<CTOptionsSubPanel> disclaimerConstraints.weighty = 0; disclaimerConstraints.weightx = 0; - contentPane.add(disclaimerPanel, disclaimerConstraints); - for (int i = 0; i < subPanels.size(); i++) { CTOptionsSubPanel subPanel = subPanels.get(i); diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.form b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.form deleted file mode 100644 index a88404c592a200dacad0601d41bd8ceec4d8c3f1..0000000000000000000000000000000000000000 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.form +++ /dev/null @@ -1,186 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> - -<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> - <TitledBorder title="Disclaimer"> - <ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/Bundle.properties" key="LicenseDisclaimerPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - <Color PropertyName="color" blue="0" green="0" red="ff" type="rgb"/> - </TitledBorder> - </Border> - </Property> - <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[2147483647, 108]"/> - </Property> - <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[562, 108]"/> - </Property> - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[400, 108]"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> - <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,108,0,0,2,50"/> - </AuxValues> - - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> - <SubComponents> - <Component class="javax.swing.JLabel" name="disclaimer"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/Bundle.properties" key="LicenseDisclaimerPanel.disclaimer.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - <Property name="verticalAlignment" type="int" value="1"/> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Container class="javax.swing.JPanel" name="spacer"> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/> - </Constraint> - </Constraints> - - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="0" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="0" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - </Layout> - </Container> - <Container class="javax.swing.JPanel" name="trialPanel"> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="10" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> - <SubComponents> - <Component class="javax.swing.JLabel" name="trialLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/Bundle.properties" key="LicenseDisclaimerPanel.trialLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="trialLink"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> - <Connection code="getHtmlLink(TRIAL_URL)" type="code"/> - </Property> - <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> - <Color id="Hand Cursor"/> - </Property> - </Properties> - <Events> - <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="trialLinkMouseClicked"/> - </Events> - <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="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - </SubComponents> - </Container> - <Container class="javax.swing.JPanel" name="purchasePanel"> - <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="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="10" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> - <SubComponents> - <Component class="javax.swing.JLabel" name="purchaseFromLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/Bundle.properties" key="LicenseDisclaimerPanel.purchaseFromLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="purchaseLink"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> - <Connection code="getHtmlLink(PURCHASE_URL)" type="code"/> - </Property> - <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> - <Color id="Hand Cursor"/> - </Property> - </Properties> - <Events> - <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="purchaseLinkMouseClicked"/> - </Events> - <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="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - </SubComponents> - </Container> - </SubComponents> -</Form> diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.java deleted file mode 100644 index 328a252467778a4307ae83cf9e060e4b0212c3b5..0000000000000000000000000000000000000000 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/LicenseDisclaimerPanel.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2023 Basis Technology Corp. - * Contact: carrier <at> sleuthkit <dot> org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.basistech.df.cybertriage.autopsy.ctoptions; - -import java.awt.Desktop; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; - -/** - * Disclaimer for license and place to purchase CT license. - */ -public class LicenseDisclaimerPanel extends javax.swing.JPanel { - - private static final Logger LOGGER = Logger.getLogger(LicenseDisclaimerPanel.class.getName()); - - private static final String TRIAL_URL = "https://cybertriage.com/autopsy-trial"; - private static final String PURCHASE_URL = "https://cybertriage.com/autopsy-checkout"; - - private static String getHtmlLink(String url) { - return "<html><span style=\"color: blue; text-decoration: underline\">" + url + "</span></html>"; - } - - /** - * Creates new form LicenseDisclaimerPanel - */ - public LicenseDisclaimerPanel() { - initComponents(); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents - private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; - - javax.swing.JLabel disclaimer = new javax.swing.JLabel(); - javax.swing.JPanel spacer = new javax.swing.JPanel(); - javax.swing.JPanel trialPanel = new javax.swing.JPanel(); - javax.swing.JLabel trialLabel = new javax.swing.JLabel(); - javax.swing.JLabel trialLink = new javax.swing.JLabel(); - javax.swing.JPanel purchasePanel = new javax.swing.JPanel(); - javax.swing.JLabel purchaseFromLabel = new javax.swing.JLabel(); - javax.swing.JLabel purchaseLink = new javax.swing.JLabel(); - - setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(LicenseDisclaimerPanel.class, "LicenseDisclaimerPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Segoe UI", 0, 12), new java.awt.Color(255, 0, 0))); // NOI18N - setMaximumSize(new java.awt.Dimension(2147483647, 108)); - setMinimumSize(new java.awt.Dimension(562, 108)); - setPreferredSize(new java.awt.Dimension(400, 108)); - setLayout(new java.awt.GridBagLayout()); - - org.openide.awt.Mnemonics.setLocalizedText(disclaimer, org.openide.util.NbBundle.getMessage(LicenseDisclaimerPanel.class, "LicenseDisclaimerPanel.disclaimer.text")); // NOI18N - disclaimer.setVerticalAlignment(javax.swing.SwingConstants.TOP); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - add(disclaimer, gridBagConstraints); - - javax.swing.GroupLayout spacerLayout = new javax.swing.GroupLayout(spacer); - spacer.setLayout(spacerLayout); - spacerLayout.setHorizontalGroup( - spacerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) - ); - spacerLayout.setVerticalGroup( - spacerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) - ); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 3; - gridBagConstraints.weighty = 1.0; - add(spacer, gridBagConstraints); - - trialPanel.setLayout(new java.awt.GridBagLayout()); - - org.openide.awt.Mnemonics.setLocalizedText(trialLabel, org.openide.util.NbBundle.getMessage(LicenseDisclaimerPanel.class, "LicenseDisclaimerPanel.trialLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - trialPanel.add(trialLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(trialLink, getHtmlLink(TRIAL_URL)); - trialLink.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - trialLink.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - trialLinkMouseClicked(evt); - } - }); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0); - trialPanel.add(trialLink, gridBagConstraints); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - add(trialPanel, gridBagConstraints); - - purchasePanel.setLayout(new java.awt.GridBagLayout()); - - org.openide.awt.Mnemonics.setLocalizedText(purchaseFromLabel, org.openide.util.NbBundle.getMessage(LicenseDisclaimerPanel.class, "LicenseDisclaimerPanel.purchaseFromLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - purchasePanel.add(purchaseFromLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(purchaseLink, getHtmlLink(PURCHASE_URL)); - purchaseLink.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - purchaseLink.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - purchaseLinkMouseClicked(evt); - } - }); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0); - purchasePanel.add(purchaseLink, gridBagConstraints); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - add(purchasePanel, gridBagConstraints); - }// </editor-fold>//GEN-END:initComponents - - private void purchaseLinkMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_purchaseLinkMouseClicked - gotoLink(PURCHASE_URL); - }//GEN-LAST:event_purchaseLinkMouseClicked - - private void trialLinkMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_trialLinkMouseClicked - gotoLink(TRIAL_URL); - }//GEN-LAST:event_trialLinkMouseClicked - - private void gotoLink(String url) { - if (Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().browse(new URI(url)); - } catch (IOException | URISyntaxException e) { - LOGGER.log(Level.SEVERE, "Error opening link to: " + url, e); - } - } else { - LOGGER.log(Level.WARNING, "Desktop API is not supported. Link cannot be opened."); - } - } - // Variables declaration - do not modify//GEN-BEGIN:variables - // End of variables declaration//GEN-END:variables -} 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 d0395d6a1af9b3129c4a10a0feab3230af9304a1..3c86b5446dc4c97322b2d9a9847caa1694de8bba 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 @@ -9,13 +9,11 @@ CTLicenseDialog.cancelButton.text=Cancel CTLicenseDialog.okButton.text=Ok CTLicenseDialog.warningLabel.text= CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text= -CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.countersResetLabel.text= -CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title=License Info CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text= CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text= CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text= -CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scans +CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scanner CTMalwareScannerOptionsPanel.licenseInfoAddButton.text=Add License CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text= CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text= @@ -24,5 +22,6 @@ CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text= EULADialog.cancelButton.text=Cancel EULADialog.acceptButton.text=Accept EULADialog.title=Cyber Triage End User License Agreement -CTMalwareScannerOptionsPanel.fileUploadCheckbox.text=Upload file if hash lookup produces no results -CTMalwareScannerOptionsPanel.fileUploadPanel.border.title=File Upload +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.purchaseFromLabel.text=For licensing information, visit 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 18e60839f3f3f38106cff8b0507a623af5221106..0e888c7facf1375c12a0f927e486e3b38032b34b 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 @@ -10,13 +10,11 @@ CTLicenseDialog.okButton.text=Ok CTLicenseDialog.warningLabel.text= CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html> CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text= -CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text= CTMalwareScannerOptionsPanel.countersResetLabel.text= -CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title=License Info CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text= CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text= CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text= -CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scans +CTMalwareScannerOptionsPanel.malwareScansPanel.border.title=Malware Scanner CTMalwareScannerOptionsPanel.licenseInfoAddButton.text=Add License CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text= CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text= @@ -62,5 +60,6 @@ CTOPtionsPanel_loadMalwareScansInfo_loading=Loading... EULADialog.cancelButton.text=Cancel EULADialog.acceptButton.text=Accept EULADialog.title=Cyber Triage End User License Agreement -CTMalwareScannerOptionsPanel.fileUploadCheckbox.text=Upload file if hash lookup produces no results -CTMalwareScannerOptionsPanel.fileUploadPanel.border.title=File Upload +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.purchaseFromLabel.text=For licensing information, visit diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicensePersistence.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicensePersistence.java index 717c4f4321348b6cb7a55c98dcb0245a7bddc95a..43e34a8d2a22238f90545e79db8081e788b9a7ea 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicensePersistence.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTLicensePersistence.java @@ -91,39 +91,6 @@ public synchronized Optional<LicenseInfo> loadLicenseInfo() { }); } - public synchronized boolean saveMalwareSettings(MalwareIngestSettings malwareIngestSettings) { - if (malwareIngestSettings != null) { - File settingsFile = getMalwareIngestFile(); - try { - settingsFile.getParentFile().mkdirs(); - objectMapper.writeValue(settingsFile, malwareIngestSettings); - return true; - } catch (IOException ex) { - logger.log(Level.WARNING, "There was an error writing malware ingest settings to file: " + settingsFile.getAbsolutePath(), ex); - } - } - - return false; - } - - public synchronized MalwareIngestSettings loadMalwareIngestSettings() { - MalwareIngestSettings settings = null; - File settingsFile = getMalwareIngestFile(); - if (settingsFile.exists() && settingsFile.isFile()) { - try { - settings = objectMapper.readValue(settingsFile, MalwareIngestSettings.class); - } catch (IOException ex) { - logger.log(Level.WARNING, "There was an error reading malware ingest settings from file: " + settingsFile.getAbsolutePath(), ex); - } - } - - if (settings == null) { - settings = new MalwareIngestSettings(); - } - - return settings; - } - private File getCTLicenseFile() { return Paths.get(PlatformUtil.getModuleConfigDirectory(), CT_SETTINGS_DIR, CT_LICENSE_FILENAME).toFile(); } diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.form b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.form index 8557f946d95770c3e1462ce2345afdbd4d85f0d5..dcdfb0a767fbbf1781161b5ef681859745589e5d 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.form +++ b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/CTMalwareScannerOptionsPanel.form @@ -11,146 +11,16 @@ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> - <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-69,0,0,1,-29"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,90,0,0,1,-29"/> </AuxValues> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> <SubComponents> - <Container class="javax.swing.JPanel" name="fileUploadPanel"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> - <TitledBorder title="File Upload"> - <ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.fileUploadPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </TitledBorder> - </Border> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> - <SubComponents> - <Component class="javax.swing.JCheckBox" name="fileUploadCheckbox"> - <Properties> - <Property name="selected" type="boolean" value="true"/> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.fileUploadCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[32767, 20]"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileUploadCheckboxActionPerformed"/> - </Events> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="1.0"/> - </Constraint> - </Constraints> - </Component> - </SubComponents> - </Container> - <Container class="javax.swing.JPanel" name="licenseInfoPanel"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> - <TitledBorder title="License Info"> - <ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </TitledBorder> - </Border> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> - <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> - </AuxValues> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> - <SubComponents> - <Component class="javax.swing.JLabel" name="licenseInfoMessageLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="licenseInfoUserLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="licenseInfoExpiresLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="licenseInfoIdLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JButton" name="licenseInfoAddButton"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoAddButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="licenseInfoAddButtonActionPerformed"/> - </Events> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="12" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - </SubComponents> - </Container> <Container class="javax.swing.JPanel" name="malwareScansPanel"> <Properties> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> - <TitledBorder title="Malware Scans"> + <TitledBorder title="Malware Scanner"> <ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.malwareScansPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </TitledBorder> </Border> @@ -164,78 +34,221 @@ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> <SubComponents> - <Component class="javax.swing.JLabel" name="malwareScansMessageLabel"> + <Component class="javax.swing.JLabel" name="disclaimer"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.disclaimer.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="verticalAlignment" type="int" value="1"/> </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> + </AuxValues> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> </Constraint> </Constraints> </Component> - <Component class="javax.swing.JLabel" name="maxHashLookupsLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> + <Container class="javax.swing.JPanel" name="licenseInfoPanel"> + <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="5" anchor="18" weightX="1.0" weightY="0.0"/> + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> </Constraint> </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="maxFileUploadsLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="countersResetLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.countersResetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="hashLookupsRemainingLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JLabel" name="fileUploadsRemainingLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="licenseInfoMessageLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="licenseInfoExpiresLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="licenseInfoIdLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="licenseInfoUserLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="licenseInfoAddButton"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.licenseInfoAddButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="licenseInfoAddButtonActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="2" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="12" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="maxFileUploadsLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="maxHashLookupsLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="hashLookupsRemainingLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="malwareScansMessageLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="countersResetLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.countersResetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="fileUploadsRemainingLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="purchasePanel"> + <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="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> </Constraint> </Constraints> - </Component> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="purchaseFromLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTMalwareScannerOptionsPanel.purchaseFromLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="purchaseLink"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getHtmlLink(PURCHASE_URL)" type="code"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Hand Cursor"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="purchaseLinkMouseClicked"/> + </Events> + <AuxValues> + <AuxValue name="generateMnemonicsCode" type="java.lang.Boolean" value="true"/> + </AuxValues> + <Constraints> + <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="3" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> </SubComponents> </Container> </SubComponents> 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 2a09c1ed5518cf3a69d834610c371b93ce16b404..375943188cba85bcf23613c24c47848a37e30da7 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 @@ -28,9 +28,12 @@ import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse; import com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil; import com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException; +import java.awt.Desktop; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Optional; @@ -73,6 +76,8 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel { private volatile String licenseInfoMessage = null; private volatile LicenseFetcher licenseFetcher = null; + private static final String PURCHASE_URL = "https://cybertriage.com/autopsy-malware-module"; + private volatile AuthTokenResponse authTokenResponse = null; private volatile String authTokenMessage = null; private volatile AuthTokenFetcher authTokenFetcher = null; @@ -114,7 +119,6 @@ public void componentShown(ComponentEvent e) { @Override public synchronized void saveSettings() { ctPersistence.saveLicenseResponse(getLicenseInfo()); - ctPersistence.saveMalwareSettings(getIngestSettings()); } @Override @@ -130,28 +134,34 @@ public synchronized void loadSettings() { setMalwareScansDisplay(null, null); if (licenseInfo != null) { loadMalwareScansInfo(licenseInfo); + this.purchaseFromLabel.setVisible(false); + this.purchaseLink.setVisible(false); + } else { + this.purchaseFromLabel.setVisible(true); + this.purchaseLink.setVisible(true); } - - MalwareIngestSettings ingestSettings = ctPersistence.loadMalwareIngestSettings(); - setIngestSettings(ingestSettings); - } - - private synchronized LicenseResponse getLicenseInfo() { - return this.licenseInfo == null ? null : this.licenseInfo.getLicenseResponse(); } - private MalwareIngestSettings getIngestSettings() { - return new MalwareIngestSettings() - .setUploadFiles(this.fileUploadCheckbox.isSelected()); + private static String getHtmlLink(String url) { + return "<html><span style=\"color: blue; text-decoration: underline\">" + url + "</span></html>"; } - private void setIngestSettings(MalwareIngestSettings ingestSettings) { - if (ingestSettings == null) { - ingestSettings = new MalwareIngestSettings(); + private void gotoLink(String url) { + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().browse(new URI(url)); + } catch (IOException | URISyntaxException e) { + logger.log(Level.SEVERE, "Error opening link to: " + url, e); + } + } else { + logger.log(Level.WARNING, "Desktop API is not supported. Link cannot be opened."); } - this.fileUploadCheckbox.setSelected(ingestSettings.isUploadFiles()); } + private synchronized LicenseResponse getLicenseInfo() { + return this.licenseInfo == null ? null : this.licenseInfo.getLicenseResponse(); + } + private synchronized void setLicenseDisplay(LicenseInfo licenseInfo, String licenseMessage) { this.licenseInfo = licenseInfo; this.licenseInfoMessage = licenseMessage; @@ -220,93 +230,78 @@ private synchronized void loadMalwareScansInfo(LicenseInfo licenseInfo) { private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; - javax.swing.JPanel fileUploadPanel = new javax.swing.JPanel(); - fileUploadCheckbox = new javax.swing.JCheckBox(); + malwareScansPanel = new javax.swing.JPanel(); + javax.swing.JLabel disclaimer = new javax.swing.JLabel(); javax.swing.JPanel licenseInfoPanel = new javax.swing.JPanel(); licenseInfoMessageLabel = new javax.swing.JLabel(); - licenseInfoUserLabel = new javax.swing.JLabel(); licenseInfoExpiresLabel = new javax.swing.JLabel(); licenseInfoIdLabel = new javax.swing.JLabel(); + licenseInfoUserLabel = new javax.swing.JLabel(); licenseInfoAddButton = new javax.swing.JButton(); - malwareScansPanel = new javax.swing.JPanel(); - malwareScansMessageLabel = new javax.swing.JLabel(); - maxHashLookupsLabel = new javax.swing.JLabel(); maxFileUploadsLabel = new javax.swing.JLabel(); - countersResetLabel = new javax.swing.JLabel(); + maxHashLookupsLabel = new javax.swing.JLabel(); hashLookupsRemainingLabel = new javax.swing.JLabel(); + malwareScansMessageLabel = new javax.swing.JLabel(); + countersResetLabel = new javax.swing.JLabel(); fileUploadsRemainingLabel = new javax.swing.JLabel(); + javax.swing.JPanel purchasePanel = new javax.swing.JPanel(); + purchaseFromLabel = new javax.swing.JLabel(); + purchaseLink = new javax.swing.JLabel(); setLayout(new java.awt.GridBagLayout()); - fileUploadPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.fileUploadPanel.border.title"))); // NOI18N - fileUploadPanel.setLayout(new java.awt.GridBagLayout()); + malwareScansPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansPanel.border.title"))); // NOI18N + malwareScansPanel.setLayout(new java.awt.GridBagLayout()); - fileUploadCheckbox.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(fileUploadCheckbox, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.fileUploadCheckbox.text")); // NOI18N - fileUploadCheckbox.setMaximumSize(new java.awt.Dimension(32767, 20)); - fileUploadCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - fileUploadCheckboxActionPerformed(evt); - } - }); + org.openide.awt.Mnemonics.setLocalizedText(disclaimer, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.disclaimer.text")); // NOI18N + disclaimer.setVerticalAlignment(javax.swing.SwingConstants.TOP); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - fileUploadPanel.add(fileUploadCheckbox, gridBagConstraints); + malwareScansPanel.add(disclaimer, gridBagConstraints); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.weightx = 1.0; - add(fileUploadPanel, gridBagConstraints); - - licenseInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoPanel.border.title"))); // NOI18N licenseInfoPanel.setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(licenseInfoMessageLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); licenseInfoPanel.add(licenseInfoMessageLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(licenseInfoUserLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(licenseInfoExpiresLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - licenseInfoPanel.add(licenseInfoUserLabel, gridBagConstraints); + licenseInfoPanel.add(licenseInfoExpiresLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(licenseInfoExpiresLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoExpiresLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(licenseInfoIdLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - licenseInfoPanel.add(licenseInfoExpiresLabel, gridBagConstraints); + licenseInfoPanel.add(licenseInfoIdLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(licenseInfoIdLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoIdLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(licenseInfoUserLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoUserLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - licenseInfoPanel.add(licenseInfoIdLabel, gridBagConstraints); + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + licenseInfoPanel.add(licenseInfoUserLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(licenseInfoAddButton, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.licenseInfoAddButton.text")); // NOI18N licenseInfoAddButton.addActionListener(new java.awt.event.ActionListener() { @@ -315,79 +310,108 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { } }); gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; + gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); licenseInfoPanel.add(licenseInfoAddButton, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(maxFileUploadsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.gridy = 4; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; - add(licenseInfoPanel, gridBagConstraints); - - malwareScansPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansPanel.border.title"))); // NOI18N - malwareScansPanel.setLayout(new java.awt.GridBagLayout()); + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + licenseInfoPanel.add(maxFileUploadsLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(malwareScansMessageLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(maxHashLookupsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - malwareScansPanel.add(malwareScansMessageLabel, gridBagConstraints); + licenseInfoPanel.add(maxHashLookupsLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(maxHashLookupsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxHashLookupsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hashLookupsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - malwareScansPanel.add(maxHashLookupsLabel, gridBagConstraints); + licenseInfoPanel.add(hashLookupsRemainingLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(maxFileUploadsLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(malwareScansMessageLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.malwareScansMessageLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - malwareScansPanel.add(maxFileUploadsLabel, gridBagConstraints); + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + licenseInfoPanel.add(malwareScansMessageLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(countersResetLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.countersResetLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 3; + gridBagConstraints.gridy = 5; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - malwareScansPanel.add(countersResetLabel, gridBagConstraints); + licenseInfoPanel.add(countersResetLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(hashLookupsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(fileUploadsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + licenseInfoPanel.add(fileUploadsRemainingLabel, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; - gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); - malwareScansPanel.add(hashLookupsRemainingLabel, gridBagConstraints); + malwareScansPanel.add(licenseInfoPanel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(fileUploadsRemainingLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.fileUploadsRemainingLabel.text")); // NOI18N + purchasePanel.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(purchaseFromLabel, org.openide.util.NbBundle.getMessage(CTMalwareScannerOptionsPanel.class, "CTMalwareScannerOptionsPanel.purchaseFromLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + purchasePanel.add(purchaseFromLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(purchaseLink, getHtmlLink(PURCHASE_URL)); + purchaseLink.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + purchaseLink.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + purchaseLinkMouseClicked(evt); + } + }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0); + purchasePanel.add(purchaseLink, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); - malwareScansPanel.add(fileUploadsRemainingLabel, gridBagConstraints); + malwareScansPanel.add(purchasePanel, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -427,9 +451,9 @@ private void licenseInfoAddButtonActionPerformed(java.awt.event.ActionEvent evt) } }//GEN-LAST:event_licenseInfoAddButtonActionPerformed - private void fileUploadCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileUploadCheckboxActionPerformed - this.firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_fileUploadCheckboxActionPerformed + private void purchaseLinkMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_purchaseLinkMouseClicked + gotoLink(PURCHASE_URL); + }//GEN-LAST:event_purchaseLinkMouseClicked @NbBundle.Messages({ "# {0} - userName", @@ -461,7 +485,12 @@ private synchronized void renderLicenseState() { this.licenseInfoExpiresLabel.setVisible(false); this.licenseInfoIdLabel.setVisible(false); this.licenseInfoUserLabel.setVisible(false); + this.purchaseFromLabel.setVisible(true); + this.purchaseLink.setVisible(true); } else { + this.purchaseFromLabel.setVisible(false); + this.purchaseLink.setVisible(false); + this.licenseInfoExpiresLabel.setVisible(true); this.licenseInfoExpiresLabel.setText(Bundle.CTMalwareScannerOptionsPanel_licenseInfo_expires( this.licenseInfo.getDecryptedLicense().getExpirationDate() == null @@ -475,8 +504,6 @@ private synchronized void renderLicenseState() { StringUtils.defaultString(this.licenseInfo.getDecryptedLicense().getCustomerEmail()))); } - this.malwareScansPanel.setVisible(StringUtils.isNotBlank(this.authTokenMessage) || authTokenResponse != null); - this.malwareScansMessageLabel.setVisible(StringUtils.isNotBlank(this.authTokenMessage)); this.malwareScansMessageLabel.setText(this.authTokenMessage); @@ -602,7 +629,18 @@ protected LicenseResponse doInBackground() throws Exception { protected void done() { try { LicenseResponse licenseResponse = get(); - SwingUtilities.invokeLater(() -> acceptEula(licenseResponse)); + 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"); + JOptionPane.showMessageDialog( + CTMalwareScannerOptionsPanel.this, + CTCloudException.ErrorCode.UN_AUTHORIZED.getDescription(), + Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title(), + JOptionPane.ERROR_MESSAGE); + setLicenseDisplay(licenseInfo, null); + loadMalwareScansInfo(licenseInfo); + } } catch (InterruptedException | CancellationException ex) { // ignore cancellation; just load current license setLicenseDisplay(licenseInfo, null); @@ -650,8 +688,8 @@ protected AuthTokenResponse doInBackground() throws Exception { if (this.isCancelled()) { return null; } - - return ctApiDAO.getAuthToken(decryptedLicense); + + return ctApiDAO.getAuthToken(decryptedLicense); } @Override @@ -691,7 +729,6 @@ protected void done() { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel countersResetLabel; - private javax.swing.JCheckBox fileUploadCheckbox; private javax.swing.JLabel fileUploadsRemainingLabel; private javax.swing.JLabel hashLookupsRemainingLabel; private javax.swing.JButton licenseInfoAddButton; @@ -703,5 +740,7 @@ protected void done() { private javax.swing.JPanel malwareScansPanel; private javax.swing.JLabel maxFileUploadsLabel; private javax.swing.JLabel maxHashLookupsLabel; + private javax.swing.JLabel purchaseFromLabel; + private javax.swing.JLabel purchaseLink; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/MalwareIngestSettings.java b/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/MalwareIngestSettings.java deleted file mode 100644 index 11e671d56106a92b37696b0caefc1f89770092d8..0000000000000000000000000000000000000000 --- a/Core/src/com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/MalwareIngestSettings.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2023 Basis Technology Corp. - * Contact: carrier <at> sleuthkit <dot> org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud; - -/** - * Settings for the malware ingest module. - */ -public class MalwareIngestSettings { - - private boolean uploadFiles = true; - - public boolean isUploadFiles() { - return uploadFiles; - } - - public MalwareIngestSettings setUploadFiles(boolean uploadFiles) { - this.uploadFiles = uploadFiles; - return this; - } - -} diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..ebde860d0bd1608a113ce5eb67149a7121f37603 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties @@ -0,0 +1,14 @@ + +# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license +# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template + +CTIncidentImportOptionsPanel.border.title=Local Settings +CTIncidentImportOptionsPanel.fileRepoPathLabel.text=Update the Cyber Triage Data Folder if you are not using the default location: +CTIncidentImportOptionsPanel.fileRepoPathField.text= +CTIncidentImportOptionsPanel.fileRepoBrowseButton.text=Browse +CTIncidentImportOptionsPanel.caseOpenWarningLabel.text=Some settings cannot be modified while a case is open. +CTIncidentImportOptionsPanel.fileRepoFileChooser.title=Cyber Triage Data Folder +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: 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 new file mode 100644 index 0000000000000000000000000000000000000000..ebde860d0bd1608a113ce5eb67149a7121f37603 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties-MERGED @@ -0,0 +1,14 @@ + +# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license +# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template + +CTIncidentImportOptionsPanel.border.title=Local Settings +CTIncidentImportOptionsPanel.fileRepoPathLabel.text=Update the Cyber Triage Data Folder if you are not using the default location: +CTIncidentImportOptionsPanel.fileRepoPathField.text= +CTIncidentImportOptionsPanel.fileRepoBrowseButton.text=Browse +CTIncidentImportOptionsPanel.caseOpenWarningLabel.text=Some settings cannot be modified while a case is open. +CTIncidentImportOptionsPanel.fileRepoFileChooser.title=Cyber Triage Data Folder +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: diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form new file mode 100644 index 0000000000000000000000000000000000000000..7382a2de2c37d8c50d05666076d40d947b50870c --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.form @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Incident Importer"> + <ResourceString PropertyName="titleX" bundle="com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties" key="CTIncidentImportOptionsPanel.border.title_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </TitledBorder> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-50,0,0,1,-17"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="incidentTextPanel"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="incidentTextLabel"> + <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.incidentTextLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="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> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="instructionsPanel"> + <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="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="instructionsTextLabel"> + <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.instructionsTextLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="For instructions on obtaining the module refer to:"/> + </AccessibilityProperties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="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"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="instructionsLinkLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getHtmlLink(CT_IMPORTER_DOC_LINK)" type="code"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Hand Cursor"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="instructionsLinkLabelMouseClicked"/> + </Events> + <Constraints> + <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"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="repoPanel"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="fileRepoPathLabel"> + <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.fileRepoPathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="2" 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> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="fileRepoPathField"> + <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.fileRepoPathField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileRepoPathFieldActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="fileRepoBrowseButton"> + <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.fileRepoBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileRepoBrowseButtonActionPerformed"/> + </Events> + <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="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="caseOpenWarningLabel"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"/> + </Property> + <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.caseOpenWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="2" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="17" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..bf018701ca70117d6b3f18107ab5c972c7664896 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTIncidentImportOptionsPanel.java @@ -0,0 +1,288 @@ +/** ************************************************************************* + ** 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). + ************************************************************************** */ +package com.basistech.df.cybertriage.autopsy.incidentoptions; + +import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel; +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.logging.Level; +import java.util.logging.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.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.guiutils.JFileChooserFactory; + +/** + * Options panel for CyberTriage options for importing a CyberTriage incident + */ +@ServiceProvider(service = CTOptionsSubPanel.class) +public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel { + + private static final Logger logger = Logger.getLogger(CTIncidentImportOptionsPanel.class.getName()); + + private static final String CT_IMPORTER_DOC_LINK = "https://docs.cybertriage.com/en/latest/chapters/integrations/autopsy.html"; + + private final JFileChooserFactory fileRepoChooserFactory = new JFileChooserFactory(); + private final CTSettingsPersistence ctPersistence = CTSettingsPersistence.getInstance(); + + private static String getHtmlLink(String url) { + return "<html><span style=\"color: blue; text-decoration: underline\">" + url + "</span></html>"; + } + + /** + * Creates new form CTIncidentImportOptionsPanel + */ + public CTIncidentImportOptionsPanel() { + initComponents(); + this.fileRepoPathField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + fireSettingsChanged(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + fireSettingsChanged(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + fireSettingsChanged(); + } + }); + + Case.addEventTypeSubscriber(Collections.singleton(Case.Events.CURRENT_CASE), (evt) -> { + CTIncidentImportOptionsPanel.this.setEnabledItems(evt.getNewValue() != null); + }); + } + + private void setCTSettingsDisplay(CTSettings ctSettings) { + this.fileRepoPathField.setText(ctSettings.getFileRepoPath()); + } + + @Override + public synchronized void saveSettings() { + ctPersistence.saveCTSettings(getSettings()); + } + + @Override + public synchronized void loadSettings() { + CTSettings ctSettings = ctPersistence.loadCTSettings(); + setCTSettingsDisplay(ctSettings); + setEnabledItems(Case.isCaseOpen()); + } + + private void setEnabledItems(boolean caseOpen) { + this.caseOpenWarningLabel.setVisible(caseOpen); + this.fileRepoBrowseButton.setEnabled(!caseOpen); + this.fileRepoPathField.setEnabled(!caseOpen); + } + + private void fireSettingsChanged() { + this.firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + + private CTSettings getSettings() { + return new CTSettings().setFileRepoPath(this.fileRepoPathField.getText()); + } + + @Override + public boolean valid() { + return new File(this.fileRepoPathField.getText()).isDirectory(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + incidentTextPanel = new javax.swing.JPanel(); + incidentTextLabel = new javax.swing.JLabel(); + instructionsPanel = new javax.swing.JPanel(); + instructionsTextLabel = new javax.swing.JLabel(); + instructionsLinkLabel = new javax.swing.JLabel(); + repoPanel = new javax.swing.JPanel(); + javax.swing.JLabel fileRepoPathLabel = new javax.swing.JLabel(); + fileRepoPathField = new javax.swing.JTextField(); + fileRepoBrowseButton = new javax.swing.JButton(); + caseOpenWarningLabel = new javax.swing.JLabel(); + + setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.border.title_1"))); // NOI18N + setLayout(new java.awt.GridBagLayout()); + + incidentTextPanel.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(incidentTextLabel, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.incidentTextLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + incidentTextPanel.add(incidentTextLabel, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + add(incidentTextPanel, gridBagConstraints); + + instructionsPanel.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(instructionsTextLabel, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.instructionsTextLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + instructionsPanel.add(instructionsTextLabel, gridBagConstraints); + instructionsTextLabel.getAccessibleContext().setAccessibleName("For instructions on obtaining the module refer to:"); + + org.openide.awt.Mnemonics.setLocalizedText(instructionsLinkLabel, getHtmlLink(CT_IMPORTER_DOC_LINK)); + instructionsLinkLabel.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + instructionsLinkLabel.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + instructionsLinkLabelMouseClicked(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + instructionsPanel.add(instructionsLinkLabel, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + add(instructionsPanel, gridBagConstraints); + + repoPanel.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(fileRepoPathLabel, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.fileRepoPathLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + repoPanel.add(fileRepoPathLabel, gridBagConstraints); + + fileRepoPathField.setText(org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.fileRepoPathField.text")); // NOI18N + fileRepoPathField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fileRepoPathFieldActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + repoPanel.add(fileRepoPathField, gridBagConstraints); + fileRepoPathField.getAccessibleContext().setAccessibleName(""); + + org.openide.awt.Mnemonics.setLocalizedText(fileRepoBrowseButton, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.fileRepoBrowseButton.text")); // NOI18N + fileRepoBrowseButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fileRepoBrowseButtonActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + repoPanel.add(fileRepoBrowseButton, gridBagConstraints); + + caseOpenWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(caseOpenWarningLabel, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.caseOpenWarningLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5); + repoPanel.add(caseOpenWarningLabel, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + add(repoPanel, gridBagConstraints); + }// </editor-fold>//GEN-END:initComponents + private void fileRepoBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileRepoBrowseButtonActionPerformed + JFileChooser fileChooser = fileRepoChooserFactory.getChooser(); + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooser.setMultiSelectionEnabled(false); + + File curSelectedDir = StringUtils.isBlank(this.fileRepoPathField.getText()) ? null : new File(this.fileRepoPathField.getText()); + if (curSelectedDir == null || !curSelectedDir.isDirectory()) { + curSelectedDir = new File(CTSettings.getDefaultFileRepoPath()); + } + + fileChooser.setCurrentDirectory(curSelectedDir); + fileChooser.setDialogTitle(org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.fileRepoFileChooser.title")); + int retVal = fileChooser.showOpenDialog(this); + if (retVal == JFileChooser.APPROVE_OPTION) { + this.fileRepoPathField.setText(fileChooser.getSelectedFile().getAbsolutePath()); + } + }//GEN-LAST:event_fileRepoBrowseButtonActionPerformed + + private void fileRepoPathFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileRepoPathFieldActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_fileRepoPathFieldActionPerformed + + private void instructionsLinkLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_instructionsLinkLabelMouseClicked + gotoLink(CT_IMPORTER_DOC_LINK); + }//GEN-LAST:event_instructionsLinkLabelMouseClicked + + private void gotoLink(String url) { + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().browse(new URI(url)); + } catch (IOException | URISyntaxException e) { + logger.log(Level.SEVERE, "Error opening link to: " + url, e); + } + } else { + logger.log(Level.WARNING, "Desktop API is not supported. Link cannot be opened."); + } + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel caseOpenWarningLabel; + private javax.swing.JButton fileRepoBrowseButton; + private javax.swing.JTextField fileRepoPathField; + private javax.swing.JLabel incidentTextLabel; + private javax.swing.JPanel incidentTextPanel; + private javax.swing.JLabel instructionsLinkLabel; + private javax.swing.JPanel instructionsPanel; + private javax.swing.JLabel instructionsTextLabel; + private javax.swing.JPanel repoPanel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..35e2d108eae0b1c5e7850e847a47cc8970c33baf --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettings.java @@ -0,0 +1,72 @@ +/** ************************************************************************* + ** 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). + ************************************************************************** */ +package com.basistech.df.cybertriage.autopsy.incidentoptions; + +import java.io.IOException; +import java.nio.file.Files; +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.openide.modules.Places; + +/** + * 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 String DEFAULT_FILE_REPO_PATH = getAppDataLocalDirectory(); + + // taken from com.basistech.df.cybertriage.utils.SystemProperties + private static String getAppDataLocalDirectory() { + + Logger LOGGER = java.util.logging.Logger.getLogger(CTSettings.class.getCanonicalName()); + 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 = Paths.get(System.getenv("LOCALAPPDATA"), "cybertriage"); + 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 + } + } + } + + public static String getDefaultFileRepoPath() { + return DEFAULT_FILE_REPO_PATH; + } + + static CTSettings getDefaultSettings() { + return new CTSettings() + .setFileRepoPath(DEFAULT_FILE_REPO_PATH); + } + + private String fileRepoPath = DEFAULT_FILE_REPO_PATH; + + public String getFileRepoPath() { + return fileRepoPath; + } + + public CTSettings setFileRepoPath(String fileRepoPath) { + this.fileRepoPath = fileRepoPath; + return this; + } +} diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java new file mode 100644 index 0000000000000000000000000000000000000000..be60813edd89a61d497290316ee69e2f3472b27c --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/incidentoptions/CTSettingsPersistence.java @@ -0,0 +1,80 @@ +/** ************************************************************************* + ** 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). + ************************************************************************** */ +package com.basistech.df.cybertriage.autopsy.incidentoptions; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; + +/** + * Handles persisting CT Settings. This code must be kept in-sync with code in + * CT Autopsy Importer NBM. + */ +public class CTSettingsPersistence { + + private static final String CT_SETTINGS_DIR = "CyberTriage"; + private static final String CT_SETTINGS_FILENAME = "CyberTriageSettings.json"; + + private static final Logger logger = Logger.getLogger(CTSettingsPersistence.class.getName()); + + private static final CTSettingsPersistence instance = new CTSettingsPersistence(); + + private final ObjectMapper objectMapper = new ObjectMapper(); + + public static CTSettingsPersistence getInstance() { + return instance; + } + + public synchronized boolean saveCTSettings(CTSettings ctSettings) { + if (ctSettings != null) { + + File settingsFile = getCTSettingsFile(); + settingsFile.getParentFile().mkdirs(); + try { + objectMapper.writeValue(settingsFile, ctSettings); + return true; + } catch (IOException ex) { + logger.log(Level.WARNING, "There was an error writing CyberTriage settings to file: " + settingsFile.getAbsolutePath(), ex); + } + } + + return false; + } + + public synchronized CTSettings loadCTSettings() { + + CTSettings settings = null; + File settingsFile = getCTSettingsFile(); + if (settingsFile.isFile()) { + try { + settings = objectMapper.readValue(settingsFile, CTSettings.class); + } catch (IOException ex) { + logger.log(Level.WARNING, "There was an error reading CyberTriage settings to file: " + settingsFile.getAbsolutePath(), ex); + } + } + + return settings == null + ? CTSettings.getDefaultSettings() + : settings; + + } + + private File getCTSettingsFile() { + return Paths.get(PlatformUtil.getModuleConfigDirectory(), CT_SETTINGS_DIR, CT_SETTINGS_FILENAME).toFile(); + } +} diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..fbf6db930c63b7e4f41099001cbd87d1b37c03e0 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties @@ -0,0 +1,7 @@ +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.AccessibleContext.accessibleName=Upload file content for files that do not have results +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.label=Upload file content for files that do not have results +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.text=Upload file content for files that do not have results +DataSourceIntegrityIngestSettingsPanel.queryFilesTextArea.text=Query for existing results using file\u2019s hash +MalwareScanIngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings +MalwareScanIngestSettingsPanel.paidLicenseTextArea.text=This module requires a paid license. \nSee the Global Options panel for details +MalwareScanIngestSettingsPanel.queryFilesCheckbox.text=Query for existing results using file\u2019s hash diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties-MERGED b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties-MERGED index 4380a9607c8ce4600aabba5cd89473c2aca49e73..decbae37cfc1479c9ffe7ad438f88e99ed44eeab 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties-MERGED +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties-MERGED @@ -38,6 +38,13 @@ MalwareScanIngestModule_uploadFile_noRemainingFileUploads_title=No Remaining Fil # {0} - objectId MalwareScanIngestModule_uploadFile_notUploadable_desc=A file did not meet requirements for upload (object id: {0}). MalwareScanIngestModule_uploadFile_notUploadable_title=Not Able to Upload -MalwareScanIngestModuleFactory_description=The malware scan ingest module queries the Cyber Triage cloud API for any possible malicious executables. +MalwareScanIngestModuleFactory_description=Identifies executable files with malware. MalwareScanIngestModuleFactory_displayName=Cyber Triage Malware Scanner MalwareScanIngestModuleFactory_version=1.0.0 +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.AccessibleContext.accessibleName=Upload file content for files that do not have results +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.label=Upload file content for files that do not have results +MalwareScanIngestSettingsPanel.uploadFilesCheckbox.text=Upload file content for files that do not have results +DataSourceIntegrityIngestSettingsPanel.queryFilesTextArea.text=Query for existing results using file\u2019s hash +MalwareScanIngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings +MalwareScanIngestSettingsPanel.paidLicenseTextArea.text=This module requires a paid license. \nSee the Global Options panel for details +MalwareScanIngestSettingsPanel.queryFilesCheckbox.text=Query for existing results using file\u2019s hash diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModule.java b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModule.java index 4698392478914b2c7858f6e840d41e96996e6b0d..bf395eb4b5d0685ef8d7b99e110a42c6ffeb29d9 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModule.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModule.java @@ -72,10 +72,17 @@ class MalwareScanIngestModule implements FileIngestModule { private static final SharedProcessing sharedProcessing = new SharedProcessing(); - + private boolean uploadFiles; + private boolean queryFiles; + + MalwareScanIngestModule(MalwareScanIngestSettings settings) { + uploadFiles = settings.shouldUploadFiles(); + queryFiles = settings.shouldQueryFiles(); + } + @Override public void startUp(IngestJobContext context) throws IngestModuleException { - sharedProcessing.startUp(context); + sharedProcessing.startUp(context, uploadFiles); } @Override @@ -123,7 +130,7 @@ private static class SharedProcessing { "application/msdos-windows",//NON-NLS "application/x-msdos-program"//NON-NLS ).collect(Collectors.toSet()); - + private static final String MALWARE_TYPE_NAME = "TSK_MALWARE"; private static final String MALWARE_CONFIG = "Cyber Triage Cloud"; @@ -153,14 +160,14 @@ private static class SharedProcessing { "MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_title=File Uploads Limit Low", "# {0} - remainingUploads", "MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_desc=This license only has {0} file uploads remaining.",}) - synchronized void startUp(IngestJobContext context) throws IngestModuleException { + synchronized void startUp(IngestJobContext context, boolean uploadFiles) throws IngestModuleException { // only run this code once per startup if (ingestJobState != null) { return; } try { - ingestJobState = getNewJobState(context); + ingestJobState = getNewJobState(context, uploadFiles); } catch (Exception ex) { ingestJobState = IngestJobState.DISABLED; throw new IngestModuleException("An exception occurred on MalwareScanIngestModule startup", ex); @@ -175,7 +182,7 @@ synchronized void startUp(IngestJobContext context) throws IngestModuleException * parameters required for the job. * @throws Exception */ - private IngestJobState getNewJobState(IngestJobContext context) throws Exception { + private IngestJobState getNewJobState(IngestJobContext context, boolean uploadFiles) throws Exception { // get saved license Optional<LicenseInfo> licenseInfoOpt = ctSettingsPersistence.loadLicenseInfo(); if (licenseInfoOpt.isEmpty() || licenseInfoOpt.get().getDecryptedLicense() == null) { @@ -207,7 +214,6 @@ private IngestJobState getNewJobState(IngestJobContext context) throws Exception } // determine lookups remaining - boolean uploadFiles = ctSettingsPersistence.loadMalwareIngestSettings().isUploadFiles(); if (uploadFiles) { long uploadsRemaining = remaining(authTokenResponse.getFileUploadLimit(), authTokenResponse.getFileUploadCount()); if (uploadsRemaining <= 0) { @@ -841,7 +847,7 @@ private AnalysisResult createAnalysisResult(IngestJobState ingestJobState, Sleut : Bundle.MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No(); String justification = cloudBean.getMalwareResult().getStatusDescription(); - + return ingestJobState.getTskCase().getBlackboard().newAnalysisResult( ingestJobState.getMalwareType(), objId, diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModuleFactory.java b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModuleFactory.java index e1381160363d093f7daff876c69d2b7febca2d9b..83cb93f689c8c2b7545bcee863c5e32a2689cb0f 100644 --- a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModuleFactory.java +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestModuleFactory.java @@ -25,6 +25,8 @@ import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; +import org.sleuthkit.autopsy.ingest.NoIngestModuleIngestJobSettings; /** * Factory for malware scan ingest modules. @@ -32,7 +34,7 @@ @ServiceProvider(service = org.sleuthkit.autopsy.ingest.IngestModuleFactory.class) @Messages({ "MalwareScanIngestModuleFactory_displayName=Cyber Triage Malware Scanner", - "MalwareScanIngestModuleFactory_description=The malware scan ingest module queries the Cyber Triage cloud API for any possible malicious executables.", + "MalwareScanIngestModuleFactory_description=Identifies executable files with malware.", "MalwareScanIngestModuleFactory_version=1.0.0" }) public class MalwareScanIngestModuleFactory extends IngestModuleFactoryAdapter { @@ -66,7 +68,7 @@ public boolean isFileIngestModuleFactory() { @Override public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) { - return new MalwareScanIngestModule(); + return new MalwareScanIngestModule((MalwareScanIngestSettings) ingestOptions); } @Override @@ -81,4 +83,23 @@ public IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() { return optionsPanel; } + @Override + public boolean hasIngestJobSettingsPanel() { + return true; + } + + @Override + public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { + if (settings instanceof MalwareScanIngestSettings) { + return new MalwareScanIngestSettingsPanel((MalwareScanIngestSettings) settings); + } + /* + * Compatibility check for older versions. + */ + if (settings instanceof NoIngestModuleIngestJobSettings) { + return new MalwareScanIngestSettingsPanel(new MalwareScanIngestSettings()); + } + + throw new IllegalArgumentException("Expected settings argument to be an instance of IngestSettings"); + } } diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettings.java b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..158e9677457664b8f0793df023b4f5845ec2e878 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettings.java @@ -0,0 +1,96 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2023 Basis Technology Corp. + * Contact: carrier <at> sleuthkit <dot> org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.basistech.df.cybertriage.autopsy.malwarescan; + +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; + +/** + * Ingest job settings for the Malware scanner module. + */ +final class MalwareScanIngestSettings implements IngestModuleIngestJobSettings { + + private static final long serialVersionUID = 1L; + + private static final boolean DEFAULT_QUERY_FILES = true; + private static final boolean DEFAULT_UPLOAD_FILES = true; + + public boolean queryFiles; + public boolean uploadFiles; + + /** + * Instantiate the ingest job settings with default values. + */ + MalwareScanIngestSettings() { + this.queryFiles = DEFAULT_QUERY_FILES; + this.uploadFiles = DEFAULT_UPLOAD_FILES; + } + + /** + * Instantiate the ingest job settings. + * + * @param computeHashes Compute hashes if none are present + * @param verifyHashes Verify hashes if any are present + */ + MalwareScanIngestSettings(boolean queryFiles, boolean uploadFiles) { + this.queryFiles = queryFiles; + this.uploadFiles = uploadFiles; + } + + @Override + public long getVersionNumber() { + return serialVersionUID; + } + + /** + * Should files be queried? + * + * @return true if files should be queried, false otherwise + */ + public boolean shouldQueryFiles() { + return queryFiles; + } + + /** + * Set whether files should be queried. + * + * @param queryFiles true if files should be queried + */ + void setqueryFiles(boolean queryFiles) { + this.queryFiles = queryFiles; + } + + + /** + * Should files be uploaded? + * + * @return true if files should be uploaded, false otherwise + */ + public boolean shouldUploadFiles() { + return uploadFiles; + } + + /** + * Set whether files should be uploaded. + * + * @param uploadFiles true if files should be uploaded + */ + void setUploadFiles(boolean uploadFiles) { + this.uploadFiles = uploadFiles; + } +} diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.form b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.form new file mode 100644 index 0000000000000000000000000000000000000000..46a928c98eda4ef9d1cd9bbdc70f65efd976632c --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.form @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 155]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="6" pref="6" max="-2" attributes="0"/> + <Component id="ingestSettingsLabel" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="6" pref="6" max="-2" attributes="0"/> + <Component id="uploadFilesCheckbox" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="queryFilesCheckbox" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="5" max="-2" attributes="0"/> + <Component id="paidLicenseTextArea" min="-2" pref="243" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="185" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="ingestSettingsLabel" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> + <Component id="queryFilesCheckbox" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="uploadFilesCheckbox" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> + <Component id="paidLicenseTextArea" min="-2" pref="32" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JCheckBox" name="queryFilesCheckbox"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.queryFilesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="uploadFilesCheckbox"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.uploadFilesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.uploadFilesCheckbox.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.uploadFilesCheckbox.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JLabel" name="ingestSettingsLabel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor"> + <FontInfo relative="true"> + <Font bold="true" component="ingestSettingsLabel" property="font" relativeSize="true" size="0"/> + </FontInfo> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.ingestSettingsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextArea" name="paidLicenseTextArea"> + <Properties> + <Property name="columns" type="int" value="20"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Segoe UI" size="12" style="1"/> + </Property> + <Property name="rows" type="int" value="5"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="com/basistech/df/cybertriage/autopsy/malwarescan/Bundle.properties" key="MalwareScanIngestSettingsPanel.paidLicenseTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="wrapStyleWord" type="boolean" value="true"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="opaque" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.java b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..a418de0f833cb32fb9fc3b81c21cc9f9342b8de0 --- /dev/null +++ b/Core/src/com/basistech/df/cybertriage/autopsy/malwarescan/MalwareScanIngestSettingsPanel.java @@ -0,0 +1,149 @@ +/* + * Autopsy Browser + * + * Copyright 2023 Basis Technology Corp. + * Contact: carrier <at> sleuthkit <dot> org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.basistech.df.cybertriage.autopsy.malwarescan; + +import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo; +import com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud.CTLicensePersistence; +import java.util.Optional; +import org.sleuthkit.autopsy.modules.dataSourceIntegrity.*; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; + +/** + * Ingest job settings panel for the Malware scanner ingest. + */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives +final class MalwareScanIngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { + + private final CTLicensePersistence ctPersistence = CTLicensePersistence.getInstance(); + + MalwareScanIngestSettingsPanel(MalwareScanIngestSettings settings) { + initComponents(); + customizeComponents(settings); + } + + /** + * Update components with values from the ingest job settings. + * + * @param settings The ingest job settings. + */ + private void customizeComponents(MalwareScanIngestSettings settings) { + Optional<LicenseInfo> licenseInfoOpt = ctPersistence.loadLicenseInfo(); + LicenseInfo licenseInfo = licenseInfoOpt.orElse(null); + if (licenseInfo != null) { + this.paidLicenseTextArea.setVisible(false); + this.queryFilesCheckbox.setVisible(true); + this.queryFilesCheckbox.setEnabled(false); + this.uploadFilesCheckbox.setVisible(true); + this.queryFilesCheckbox.setSelected(true); + this.uploadFilesCheckbox.setSelected(settings.shouldUploadFiles()); + } else { + this.paidLicenseTextArea.setVisible(true); + this.queryFilesCheckbox.setVisible(false); + this.uploadFilesCheckbox.setVisible(false); + } + } + + @Override + public IngestModuleIngestJobSettings getSettings() { + return new MalwareScanIngestSettings(queryFilesCheckbox.isSelected(), uploadFilesCheckbox.isSelected()); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + queryFilesCheckbox = new javax.swing.JCheckBox(); + uploadFilesCheckbox = new javax.swing.JCheckBox(); + ingestSettingsLabel = new javax.swing.JLabel(); + paidLicenseTextArea = new javax.swing.JTextArea(); + + setPreferredSize(new java.awt.Dimension(300, 155)); + + queryFilesCheckbox.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(queryFilesCheckbox, org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.queryFilesCheckbox.text")); // NOI18N + queryFilesCheckbox.setEnabled(false); + + org.openide.awt.Mnemonics.setLocalizedText(uploadFilesCheckbox, org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.uploadFilesCheckbox.text")); // NOI18N + uploadFilesCheckbox.setFocusable(false); + uploadFilesCheckbox.setLabel(org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.uploadFilesCheckbox.label")); // NOI18N + + ingestSettingsLabel.setFont(ingestSettingsLabel.getFont().deriveFont(ingestSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD)); + org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.ingestSettingsLabel.text")); // NOI18N + + paidLicenseTextArea.setColumns(20); + paidLicenseTextArea.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N + paidLicenseTextArea.setRows(5); + paidLicenseTextArea.setText(org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.paidLicenseTextArea.text")); // NOI18N + paidLicenseTextArea.setWrapStyleWord(true); + paidLicenseTextArea.setBorder(null); + paidLicenseTextArea.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + paidLicenseTextArea.setFocusable(false); + paidLicenseTextArea.setOpaque(false); + paidLicenseTextArea.setRequestFocusEnabled(false); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(ingestSettingsLabel)) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(uploadFilesCheckbox)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(queryFilesCheckbox)) + .addGroup(layout.createSequentialGroup() + .addGap(5, 5, 5) + .addComponent(paidLicenseTextArea, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(185, 185, 185)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(ingestSettingsLabel) + .addGap(18, 18, 18) + .addComponent(queryFilesCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(uploadFilesCheckbox) + .addGap(18, 18, 18) + .addComponent(paidLicenseTextArea, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + uploadFilesCheckbox.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(MalwareScanIngestSettingsPanel.class, "MalwareScanIngestSettingsPanel.uploadFilesCheckbox.AccessibleContext.accessibleName")); // NOI18N + }// </editor-fold>//GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel ingestSettingsLabel; + private javax.swing.JTextArea paidLicenseTextArea; + private javax.swing.JCheckBox queryFilesCheckbox; + private javax.swing.JCheckBox uploadFilesCheckbox; + // End of variables declaration//GEN-END:variables + +}