/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.quicksetup.installer.ui; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.security.KeyStoreException; import java.util.ArrayList; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.text.JTextComponent; import org.opends.quicksetup.SecurityOptions; import org.opends.quicksetup.event.BrowseActionListener; import org.opends.quicksetup.event.MinimumSizeComponentListener; import org.opends.quicksetup.i18n.ResourceProvider; import org.opends.quicksetup.installer.Installer; import org.opends.quicksetup.ui.UIFactory; import org.opends.quicksetup.util.BackgroundTask; import org.opends.quicksetup.util.Utils; import org.opends.server.util.CertificateManager; /** * This class is a dialog that appears when the user wants to configure * security parameters for the new OpenDS instance. */ public class SecurityOptionsDialog extends JDialog { private static final long serialVersionUID = 4083707346899442215L; private JCheckBox cbEnableSSL; private JCheckBox cbEnableStartTLS; private JTextField tfPort; private JRadioButton rbUseSelfSignedCertificate; private JRadioButton rbUseExistingCertificate; private JLabel lSelfSignedName; private JTextField tfSelfSignedName; private JLabel lKeystoreType; private JRadioButton rbPKCS11; private JRadioButton rbJKS; private JRadioButton rbPKCS12; private JLabel lKeystorePath; private JTextField tfKeystorePath; private JButton browseButton; private JLabel lKeystorePwd; private JPasswordField tfKeystorePwd; private JButton cancelButton; private JButton okButton; private SelectAliasDialog aliasDlg; private boolean isCancelled = true; private SecurityOptions securityOptions; private String[] aliases; private String selectedAlias; private final int DEFAULT_PORT = 636; /** * Constructor of the SecurityOptionsDialog. * @param parent the parent frame for this dialog. * @param options the SecurityOptions used to populate this dialog. * @throws IllegalArgumentException if options is null. */ public SecurityOptionsDialog(JFrame parent, SecurityOptions options) throws IllegalArgumentException { super(parent); setTitle(getMsg("security-options-dialog-title")); securityOptions = options; getContentPane().add(createPanel()); pack(); updateContents(); int minWidth = (int) getPreferredSize().getWidth(); int minHeight = (int) getPreferredSize().getHeight(); addComponentListener(new MinimumSizeComponentListener(this, minWidth, minHeight)); getRootPane().setDefaultButton(okButton); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { cancelClicked(); } }); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); Utils.centerOnComponent(this, parent); } /** * Returns true if the user clicked on cancel and * false otherwise. * @return true if the user clicked on cancel and * false otherwise. */ public boolean isCancelled() { return isCancelled; } /** * Displays this dialog and populates its contents with the provided * SecurityOptions object. * @param options the SecurityOptions used to populate this dialog. * @throws IllegalArgumentException if options is null. */ public void display(SecurityOptions options) throws IllegalArgumentException { if (options == null) { throw new IllegalArgumentException("options parameter cannot be null."); } UIFactory.setTextStyle(cbEnableSSL, UIFactory.TextStyle.SECONDARY_FIELD_VALID); UIFactory.setTextStyle(lSelfSignedName, UIFactory.TextStyle.SECONDARY_FIELD_VALID); UIFactory.setTextStyle(lKeystorePath, UIFactory.TextStyle.SECONDARY_FIELD_VALID); UIFactory.setTextStyle(lKeystorePwd, UIFactory.TextStyle.SECONDARY_FIELD_VALID); securityOptions = options; updateContents(); isCancelled = true; setVisible(true); } /** * Returns the security options object representing the input of the user * in this panel. * @return the security options object representing the input of the user * in this panel. */ public SecurityOptions getSecurityOptions() { SecurityOptions ops; boolean enableSSL = cbEnableSSL.isSelected(); boolean enableStartTLS = cbEnableStartTLS.isSelected(); if (enableSSL || enableStartTLS) { int sslPort = -1; try { sslPort = Integer.parseInt(tfPort.getText()); } catch (Throwable t) { } if (rbUseSelfSignedCertificate.isSelected()) { ops = SecurityOptions.createSelfSignedCertificateOptions( tfSelfSignedName.getText(), enableSSL, enableStartTLS, sslPort); } else if (rbJKS.isSelected()) { ops = SecurityOptions.createJKSCertificateOptions( tfKeystorePath.getText(), String.valueOf(tfKeystorePwd.getPassword()), enableSSL, enableStartTLS, sslPort, selectedAlias); } else if (rbPKCS11.isSelected()) { ops = SecurityOptions.createPKCS11CertificateOptions( String.valueOf(tfKeystorePwd.getPassword()), enableSSL, enableStartTLS, sslPort, selectedAlias); } else if (rbPKCS12.isSelected()) { ops = SecurityOptions.createPKCS12CertificateOptions( tfKeystorePath.getText(), String.valueOf(tfKeystorePwd.getPassword()), enableSSL, enableStartTLS, sslPort, selectedAlias); } else { throw new IllegalStateException("No certificate options selected."); } } else { ops = SecurityOptions.createNoCertificateOptions(); } return ops; } /** * Creates and returns the panel of the dialog. * @return the panel of the dialog. */ private JPanel createPanel() { GridBagConstraints gbc = new GridBagConstraints(); JPanel contentPanel = new JPanel(new GridBagLayout()); contentPanel.setBackground(UIFactory.DEFAULT_BACKGROUND); gbc.insets = UIFactory.getEmptyInsets(); gbc.fill = GridBagConstraints.BOTH; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 1.0; JPanel topPanel = new JPanel(new GridBagLayout()); topPanel.setBorder(UIFactory.DIALOG_PANEL_BORDER); topPanel.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND); Insets insets = UIFactory.getCurrentStepPanelInsets(); gbc.weighty = 0.0; insets.bottom = 0; gbc.insets = insets; topPanel.add(createTitlePanel(), gbc); gbc.insets.top = UIFactory.TOP_INSET_INSTRUCTIONS_SUBPANEL; topPanel.add(createInstructionsPane(), gbc); gbc.insets.top = UIFactory.TOP_INSET_INPUT_SUBPANEL; gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL; topPanel.add(createInputPanel(), gbc); gbc.weighty = 1.0; gbc.insets = UIFactory.getEmptyInsets(); topPanel.add(Box.createVerticalGlue(), gbc); contentPanel.add(topPanel, gbc); gbc.weighty = 0.0; gbc.insets = UIFactory.getButtonsPanelInsets(); contentPanel.add(createButtonsPanel(), gbc); return contentPanel; } /** * Creates and returns the title sub panel. * @return the title sub panel. */ private Component createTitlePanel() { JPanel titlePanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); titlePanel.setOpaque(false); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 0.0; gbc.gridwidth = GridBagConstraints.RELATIVE; String title = getMsg("security-options-title"); JLabel l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title, UIFactory.TextStyle.TITLE); l.setOpaque(false); titlePanel.add(l, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets.left = 0; gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; titlePanel.add(Box.createHorizontalGlue(), gbc); return titlePanel; } /** * Creates and returns the instructions sub panel. * @return the instructions sub panel. */ private Component createInstructionsPane() { String instructions = getMsg("security-options-instructions"); JTextComponent instructionsPane = UIFactory.makeHtmlPane(instructions, UIFactory.INSTRUCTIONS_FONT); instructionsPane.setOpaque(false); instructionsPane.setEditable(false); return instructionsPane; } /** * Creates and returns the input sub panel: the panel with all the widgets * that are used to define the security options. * @return the input sub panel. */ private Component createInputPanel() { JPanel inputPanel = new JPanel(new GridBagLayout()); inputPanel.setOpaque(false); ActionListener l = new ActionListener() { public void actionPerformed(ActionEvent ev) { updateEnablingState(); } }; cbEnableSSL = UIFactory.makeJCheckBox(getMsg("enable-ssl-label"), getMsg("enable-ssl-tooltip"), UIFactory.TextStyle.PRIMARY_FIELD_VALID); cbEnableSSL.addActionListener(l); String sPort = ""; int port = securityOptions.getSslPort(); if (port > 0) { sPort = String.valueOf(port); } tfPort = UIFactory.makeJTextField(sPort, getMsg("ssl-port-textfield-tooltip"), UIFactory.PORT_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD); cbEnableStartTLS = UIFactory.makeJCheckBox(getMsg("enable-starttls-label"), getMsg("enable-starttls-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); cbEnableStartTLS.addActionListener(l); rbUseSelfSignedCertificate = UIFactory.makeJRadioButton( getMsg("use-self-signed-label"), getMsg("use-self-signed-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); rbUseSelfSignedCertificate.addActionListener(l); lSelfSignedName = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("self-signed-certificate-name-label"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); lSelfSignedName.setOpaque(false); String selfSignedName = securityOptions.getSelfSignedCertificateName(); tfSelfSignedName = UIFactory.makeJTextField(selfSignedName, getMsg("self-signed-certificate-name-tooltip"), UIFactory.HOST_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD); lSelfSignedName.setLabelFor(tfSelfSignedName); rbUseExistingCertificate = UIFactory.makeJRadioButton( getMsg("use-existing-certificate-label"), getMsg("use-existing-certificate-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); rbUseExistingCertificate.addActionListener(l); ButtonGroup group1 = new ButtonGroup(); group1.add(rbUseSelfSignedCertificate); group1.add(rbUseExistingCertificate); lKeystoreType = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("keystore-type-label"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); lKeystoreType.setOpaque(false); rbJKS = UIFactory.makeJRadioButton( getMsg("jks-certificate-label"), getMsg("jks-certificate-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); rbJKS.addActionListener(l); rbPKCS11 = UIFactory.makeJRadioButton( getMsg("pkcs11-certificate-label"), getMsg("pkcs11-certificate-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); rbPKCS11.addActionListener(l); rbPKCS12 = UIFactory.makeJRadioButton( getMsg("pkcs12-certificate-label"), getMsg("pkcs12-certificate-tooltip"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); rbPKCS12.addActionListener(l); ButtonGroup group2 = new ButtonGroup(); group2.add(rbJKS); group2.add(rbPKCS11); group2.add(rbPKCS12); lKeystoreType.setLabelFor(rbJKS); lKeystorePath = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("keystore-path-label"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); lKeystorePath.setOpaque(false); tfKeystorePath = UIFactory.makeJTextField("", getMsg("keystore-path-tooltip"), UIFactory.HOST_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD); lKeystorePath.setLabelFor(tfKeystorePath); browseButton = UIFactory.makeJButton(getMsg("browse-button-label"), getMsg("browse-button-tooltip")); BrowseActionListener browseListener = new BrowseActionListener(tfKeystorePath, BrowseActionListener.BrowseType.GENERIC_FILE, this); browseButton.addActionListener(browseListener); lKeystorePwd = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("keystore-pwd-label"), UIFactory.TextStyle.SECONDARY_FIELD_VALID); lKeystorePwd.setOpaque(false); tfKeystorePwd = UIFactory.makeJPasswordField("", getMsg("keystore-pwd-tooltip"), UIFactory.PASSWORD_FIELD_SIZE, UIFactory.TextStyle.PASSWORD_FIELD); lKeystorePwd.setLabelFor(tfKeystorePwd); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 0.0; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets = UIFactory.getEmptyInsets(); gbc.fill = GridBagConstraints.HORIZONTAL; inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("ssl-access-label"), UIFactory.TextStyle.PRIMARY_FIELD_VALID), gbc); JPanel auxPanel = new JPanel(new GridBagLayout()); auxPanel.setOpaque(false); gbc.gridwidth = 4; gbc.fill = GridBagConstraints.NONE; auxPanel.add(cbEnableSSL, gbc); gbc.gridwidth--; gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD; auxPanel.add(tfPort, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; auxPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getPortHelpMessage(), UIFactory.TextStyle.SECONDARY_FIELD_VALID), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; auxPanel.add(Box.createHorizontalGlue(), gbc); gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD; gbc.weightx = 1.0; inputPanel.add(auxPanel, gbc); gbc.insets = UIFactory.getEmptyInsets(); gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.weightx = 0.0; inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("starttls-access-label"), UIFactory.TextStyle.PRIMARY_FIELD_VALID), gbc); auxPanel = new JPanel(new GridBagLayout()); auxPanel.setOpaque(false); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets = UIFactory.getEmptyInsets(); auxPanel.add(cbEnableStartTLS, gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; auxPanel.add(Box.createHorizontalGlue(), gbc); gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD; gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; inputPanel.add(auxPanel, gbc); gbc.insets = UIFactory.getEmptyInsets(); gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.weightx = 0.0; JLabel lCertificate = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, getMsg("certificate-label"), UIFactory.TextStyle.PRIMARY_FIELD_VALID); int additionalInset = Math.abs(lCertificate.getPreferredSize().height - rbUseSelfSignedCertificate.getPreferredSize().height) / 2; gbc.insets.top += additionalInset; inputPanel.add(lCertificate, gbc); auxPanel = new JPanel(new GridBagLayout()); auxPanel.setOpaque(false); gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 1.0; gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; inputPanel.add(auxPanel, gbc); gbc.insets = UIFactory.getEmptyInsets(); gbc.anchor = GridBagConstraints.WEST; JPanel aux2Panel = new JPanel(new GridBagLayout()); aux2Panel.setOpaque(false); gbc.gridwidth = GridBagConstraints.RELATIVE; aux2Panel.add(rbUseSelfSignedCertificate, gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; aux2Panel.add(Box.createHorizontalGlue(), gbc); auxPanel.add(aux2Panel, gbc); aux2Panel = new JPanel(new GridBagLayout()); aux2Panel.setOpaque(false); gbc.weightx = 0.0; gbc.gridwidth = 3; aux2Panel.add(lSelfSignedName, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD; aux2Panel.add(tfSelfSignedName, gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets.left = 0; aux2Panel.add(Box.createHorizontalGlue(), gbc); gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE; auxPanel.add(aux2Panel, gbc); aux2Panel = new JPanel(new GridBagLayout()); aux2Panel.setOpaque(false); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets = UIFactory.getEmptyInsets(); gbc.weightx = 0.0; aux2Panel.add(rbUseExistingCertificate, gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; aux2Panel.add(Box.createHorizontalGlue(), gbc); gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; auxPanel.add(aux2Panel, gbc); additionalInset = Math.abs(lKeystoreType.getPreferredSize().height - rbJKS.getPreferredSize().height) / 2; aux2Panel = new JPanel(new GridBagLayout()); aux2Panel.setOpaque(false); gbc.insets.top -= additionalInset; gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE; auxPanel.add(aux2Panel, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets = UIFactory.getEmptyInsets(); gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets.top = additionalInset; aux2Panel.add(lKeystoreType, gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets.top = 0; aux2Panel.add(rbJKS, gbc); gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON; gbc.gridwidth = GridBagConstraints.RELATIVE; aux2Panel.add(Box.createHorizontalGlue(), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; aux2Panel.add(rbPKCS12, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; aux2Panel.add(Box.createHorizontalGlue(), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; aux2Panel.add(rbPKCS11, gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets.left = 0; gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.WEST; aux2Panel.add(lKeystorePath, gbc); JPanel aux3Panel = new JPanel(new GridBagLayout()); aux3Panel.setOpaque(false); gbc.weightx = 1.0; gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD; gbc.gridwidth = GridBagConstraints.REMAINDER; aux2Panel.add(aux3Panel, gbc); gbc.insets = UIFactory.getEmptyInsets(); gbc.gridwidth = GridBagConstraints.RELATIVE; aux3Panel.add(tfKeystorePath, gbc); gbc.insets.left = UIFactory.LEFT_INSET_BROWSE; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 0.0; aux3Panel.add(browseButton, gbc); gbc.insets.left = 0; gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.WEST; aux2Panel.add(lKeystorePwd, gbc); gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.NONE; aux2Panel.add(tfKeystorePwd, gbc); return inputPanel; } /** * Creates and returns the buttons OK/CANCEL sub panel. * @return the buttons OK/CANCEL sub panel. */ private Component createButtonsPanel() { JPanel buttonsPanel = new JPanel(new GridBagLayout()); buttonsPanel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = 4; gbc.insets = UIFactory.getEmptyInsets(); gbc.insets.left = UIFactory.getCurrentStepPanelInsets().left; buttonsPanel.add(UIFactory.makeJLabel(UIFactory.IconType.OPENDS_SMALL, null, UIFactory.TextStyle.NO_STYLE), gbc); gbc.weightx = 1.0; gbc.gridwidth--; gbc.insets.left = 0; buttonsPanel.add(Box.createHorizontalGlue(), gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; okButton = UIFactory.makeJButton(getMsg("ok-button-label"), getMsg("security-options-ok-button-tooltip")); buttonsPanel.add(okButton, gbc); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { okClicked(); } }); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS; cancelButton = UIFactory.makeJButton(getMsg("cancel-button-label"), getMsg("security-options-cancel-button-tooltip")); buttonsPanel.add(cancelButton, gbc); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { cancelClicked(); } }); return buttonsPanel; } /** * Method called when user clicks on cancel. * */ private void cancelClicked() { isCancelled = true; dispose(); } /** * Method called when user clicks on OK. * */ private void okClicked() { BackgroundTask worker = new BackgroundTask() { public Object processBackgroundTask() { ArrayList errorMsgs = new ArrayList(); errorMsgs.addAll(checkPort()); errorMsgs.addAll(checkSelfSigned()); errorMsgs.addAll(checkKeystore()); return errorMsgs; } public void backgroundTaskCompleted(Object returnValue, Throwable throwable) { if (throwable != null) { // Bug throwable.printStackTrace(); displayError( Utils.getThrowableMsg(getI18n(), "bug-msg", null, throwable), getMsg("error-title")); cancelButton.setEnabled(true); okButton.setEnabled(true); } else { cancelButton.setEnabled(true); okButton.setEnabled(true); ArrayList ar = (ArrayList)returnValue; if (ar.size() > 0) { ArrayList errorMsgs = new ArrayList(); for (Object o: ar) { errorMsgs.add((String)o); } displayError(Utils.getStringFromCollection(errorMsgs, "\n"), getMsg("error-title")); } else { if (rbUseExistingCertificate.isSelected() && (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected())) { if (aliases.length > 1) { if (aliasDlg == null) { aliasDlg = new SelectAliasDialog(SecurityOptionsDialog.this); } aliasDlg.display(aliases); if (!aliasDlg.isCancelled()) { selectedAlias = aliasDlg.getSelectedAlias(); isCancelled = false; dispose(); } } else { selectedAlias = aliases[0]; isCancelled = false; dispose(); } } else { isCancelled = false; dispose(); } } } } }; cancelButton.setEnabled(false); okButton.setEnabled(false); worker.startBackgroundTask(); } /** * Displays an error message dialog. * * @param msg * the error message. * @param title * the title for the dialog. */ private void displayError(String msg, String title) { Utils.displayError(this, msg, title); toFront(); } /** * Updates the widgets on the dialog with the contents of the securityOptions * object. * */ private void updateContents() { cbEnableSSL.setSelected(securityOptions.getEnableSSL()); cbEnableStartTLS.setSelected(securityOptions.getEnableStartTLS()); if (securityOptions.getEnableSSL()) { int port = securityOptions.getSslPort(); if (port > 0) { tfPort.setText(String.valueOf(port)); } } switch (securityOptions.getCertificateType()) { case NO_CERTIFICATE: // Nothing else to do break; case SELF_SIGNED_CERTIFICATE: rbUseSelfSignedCertificate.setSelected(true); tfSelfSignedName.setText(securityOptions.getSelfSignedCertificateName()); break; case JKS: rbUseExistingCertificate.setSelected(true); rbJKS.setSelected(true); tfKeystorePath.setText(securityOptions.getKeystorePath()); tfKeystorePwd.setText(securityOptions.getKeystorePassword()); break; case PKCS11: rbUseExistingCertificate.setSelected(true); rbPKCS11.setSelected(true); tfKeystorePwd.setText(securityOptions.getKeystorePassword()); break; case PKCS12: rbUseExistingCertificate.setSelected(true); rbPKCS12.setSelected(true); tfKeystorePath.setText(securityOptions.getKeystorePath()); tfKeystorePwd.setText(securityOptions.getKeystorePassword()); break; default: throw new IllegalStateException("Unknown certificate type."); } updateEnablingState(); } /** * Enables/disables and makes visible/invisible the objects according to what * the user selected. */ private void updateEnablingState() { boolean enableSSL = cbEnableSSL.isSelected(); boolean enableStartTLS = cbEnableStartTLS.isSelected(); boolean useSSL = enableSSL || enableStartTLS; if (useSSL && !rbUseSelfSignedCertificate.isSelected() && !rbUseExistingCertificate.isSelected()) { rbUseSelfSignedCertificate.setSelected(true); } if (useSSL && rbUseExistingCertificate.isSelected() && !rbJKS.isSelected() && !rbPKCS11.isSelected() && !rbPKCS12.isSelected()) { rbJKS.setSelected(true); } tfPort.setEnabled(enableSSL); rbUseSelfSignedCertificate.setEnabled(useSSL); lSelfSignedName.setEnabled( rbUseSelfSignedCertificate.isSelected() && useSSL); tfSelfSignedName.setEnabled( rbUseSelfSignedCertificate.isSelected() && useSSL); rbUseExistingCertificate.setEnabled(useSSL); lKeystoreType.setEnabled( rbUseExistingCertificate.isSelected() && useSSL); rbJKS.setEnabled(rbUseExistingCertificate.isSelected() && useSSL); rbPKCS11.setEnabled(rbUseExistingCertificate.isSelected() && useSSL); rbPKCS12.setEnabled(rbUseExistingCertificate.isSelected() && useSSL); lKeystorePath.setEnabled( rbUseExistingCertificate.isSelected() && useSSL); tfKeystorePath.setEnabled( rbUseExistingCertificate.isSelected() && useSSL); browseButton.setEnabled(rbUseExistingCertificate.isSelected() && useSSL); lKeystorePwd.setEnabled( rbUseExistingCertificate.isSelected() && useSSL); tfKeystorePwd.setEnabled( rbUseExistingCertificate.isSelected() && useSSL); lKeystorePath.setVisible(!rbPKCS11.isSelected()); tfKeystorePath.setVisible(!rbPKCS11.isSelected()); browseButton.setVisible(!rbPKCS11.isSelected()); } /** * Returns the port help message that we display when we cannot use the * default port (636). * @return the port help message that we display when we cannot use the * default port (636). */ private String getPortHelpMessage() { String s = ""; if (securityOptions.getSslPort() != DEFAULT_PORT) { s = getMsg("cannot-use-default-secure-port"); } return s; } /* The following three methods are just commodity methods to retrieve * localized messages */ private String getMsg(String key) { return getI18n().getMsg(key); } private String getMsg(String key, String[] args) { return getI18n().getMsg(key, args); } private ResourceProvider getI18n() { return ResourceProvider.getInstance(); } /** * Checks the port. * @return the error messages found while checking the port. */ private ArrayList checkPort() { ArrayList errorMsgs = new ArrayList(); if (cbEnableSSL.isSelected()) { /* Check the port. */ String sPort = tfPort.getText(); int port = -1; try { port = Integer.parseInt(sPort); if ((port < Installer.MIN_PORT_VALUE) || (port > Installer.MAX_PORT_VALUE)) { String[] args = { String.valueOf(Installer.MIN_PORT_VALUE), String.valueOf(Installer.MAX_PORT_VALUE) }; errorMsgs.add(getMsg("invalid-secure-port-value-range", args)); } else if (!Utils.canUseAsPort(port)) { if (Utils.isPriviledgedPort(port)) { errorMsgs.add(getMsg("cannot-bind-priviledged-port", new String[] { String.valueOf(port) })); } else { errorMsgs.add(getMsg("cannot-bind-port", new String[] { String.valueOf(port) })); } } } catch (NumberFormatException nfe) { String[] args = { String.valueOf(Installer.MIN_PORT_VALUE), String.valueOf(Installer.MAX_PORT_VALUE) }; errorMsgs.add(getMsg("invalid-secure-port-value-range", args)); } } setValidLater(cbEnableSSL, errorMsgs.size() == 0); return errorMsgs; } /** * Checks the self-signed certificate parameters. * @return the error messages found while checking self-signed certificate * parameters. */ private ArrayList checkSelfSigned() { ArrayList errorMsgs = new ArrayList(); if (rbUseSelfSignedCertificate.isSelected() && (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected())) { String name = tfSelfSignedName.getText(); if ((name != null) && (name.length() > 0)) { /* TODO: We might try to do something to check if the user provided a * valid host name, but we cannot guarantee that the check will be valid * AND we might want to allow the user to use a common name for the * certificate that is not the host name. */ } else { errorMsgs.add(getMsg("no-self-signed-cert-name-provided")); } } setValidLater(lSelfSignedName, errorMsgs.size() == 0); return errorMsgs; } /** * Checks the existing keystore parameters. * @return the error messages found while checking existing keystore * parameters. */ private ArrayList checkKeystore() { ArrayList errorMsgs = new ArrayList(); boolean pathValid = true; boolean pwdValid = true; if (rbUseExistingCertificate.isSelected() && (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected())) { String path = tfKeystorePath.getText(); if (rbJKS.isSelected() || rbPKCS12.isSelected()) { /* Check the path */ if ((path == null) || (path.length() == 0)) { errorMsgs.add(getMsg("keystore-path-not-provided")); } else { File f = new File(path); if (!f.exists()) { errorMsgs.add(getMsg("keystore-path-does-not-exist")); } else if (!f.isFile()) { errorMsgs.add(getMsg("keystore-path-not-a-file")); } } pathValid = errorMsgs.size() == 0; } /* Check the password */ String pwd = String.valueOf(tfKeystorePwd.getPassword()); if ((pwd == null) || (pwd.length() == 0)) { errorMsgs.add(getMsg("keystore-pwd-empty")); pwdValid = false; } if (pathValid && pwdValid) { // TODO: put the password in a temporary file to do the checks. try { CertificateManager certManager; if (rbJKS.isSelected()) { certManager = new CertificateManager( path, CertificateManager.KEY_STORE_TYPE_JKS, pwd); } else if (rbPKCS12.isSelected()) { certManager = new CertificateManager( path, CertificateManager.KEY_STORE_TYPE_PKCS12, pwd); } else if (rbPKCS11.isSelected()) { certManager = new CertificateManager( CertificateManager.KEY_STORE_PATH_PKCS11, CertificateManager.KEY_STORE_TYPE_PKCS11, pwd); } else { throw new IllegalStateException("No keystore type selected."); } aliases = certManager.getCertificateAliases(); if ((aliases == null) || (aliases.length == 0)) { // Could not retrieve any certificate if (rbPKCS11.isSelected()) { errorMsgs.add(getMsg("pkcs11-keystore-does-not-exist")); } else { if (rbJKS.isSelected()) { errorMsgs.add(getMsg("jks-keystore-does-not-exist")); } else { errorMsgs.add(getMsg("pkcs12-keystore-does-not-exist")); } pathValid = false; } } } catch (KeyStoreException ke) { pwdValid = false; if (!rbPKCS11.isSelected()) { pathValid = false; } // Could not access to the keystore: because the password is no good, // because the provided file is not a valid keystore, etc. if (rbPKCS11.isSelected()) { errorMsgs.add(getMsg("error-accessing-pkcs11-keystore")); } else { if (rbJKS.isSelected()) { errorMsgs.add(getMsg("error-accessing-jks-keystore")); } else { errorMsgs.add(getMsg("error-accessing-pkcs12-keystore")); } pathValid = false; } } } } setValidLater(lKeystorePath, pathValid); setValidLater(lKeystorePwd, pwdValid); return errorMsgs; } /** * Method that updates the text style of a provided component by calling * SwingUtilities.invokeLater. This method is aimed to be called outside * the event thread (calling it from the event thread will also work though). * @param comp the component to be updated. * @param valid whether to use a TextStyle to mark the component as valid * or as invalid. */ private void setValidLater(final JComponent comp, final boolean valid) { SwingUtilities.invokeLater(new Runnable() { public void run() { UIFactory.setTextStyle(comp, valid ? UIFactory.TextStyle.SECONDARY_FIELD_VALID : UIFactory.TextStyle.SECONDARY_FIELD_INVALID); } }); } /** * Method written for testing purposes. * @param args the arguments to be passed to the test program. */ public static void main(String[] args) { try { // UIFactory.initialize(); SecurityOptionsDialog dlg = new SecurityOptionsDialog(new JFrame(), SecurityOptions.createNoCertificateOptions()); dlg.pack(); dlg.setVisible(true); } catch (Exception ex) { ex.printStackTrace(); } } }