mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
19.55.2007 71512d1aab25aae01c2d74f0d5c40e6dc0e809c3
The following changes are targetted to extend the Graphical Setup and provide the possibility of configuring SSL and Start TLS.

In the particular case where the user provides a keystore with multiple certificates, the user is prompted to choose one of the certificates.

The committed changes include Neil's wording proposal and fix both the bug he found using PKCS#11 and the layout problem.

When the user chooses to enable SSL or StartTLS, the code does the following:

* In the particular case of the self-signed certificate a random password is generated and a JKS keystore is created under <server_root>/config/keystore.

* In all cases where the password to access the keystore is stored in clear under <server_root>/config/keystore.pin.

* In all cases a JKS Trust Store containing the server certificate is created under <server_root>/config/truststore. Please tell whether using a Blind Trust Manager is a better alternative.

Known Issues and Limitations
============================

The code in CertificateManager must be updated to avoid calling keytool with the password in clear.

The setup will not work if the keystore's password and the certificate key password are different.

3 files added
19 files modified
3343 ■■■■■ changed files
opends/build.xml 2 ●●●●● patch | view | raw | blame | history
opends/resource/FindJavaHome.class patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Launcher.java 17 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java 356 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 86 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java 17 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 390 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java 35 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 100 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java 6 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java 86 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java 1188 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java 275 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java 160 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java 1 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ConfigMessages.java 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ProtocolMessages.java 12 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ToolMessages.java 185 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ConfigureDS.java 404 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/CertificateManager.java 15 ●●●●● patch | view | raw | blame | history
opends/build.xml
@@ -457,6 +457,7 @@
               target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
               memoryMaximumSize="${MEM}">
      <include name="**/org/opends/server/util/SetupUtils.java"/>
        <include name="**/org/opends/server/util/CertificateManager.java"/>
      <include name="**/org/opends/server/util/DynamicConstants.java"/>
      <include name="**/org/opends/server/types/OperatingSystem.java"/>
      <compilerarg value="-Xlint:all" />
@@ -561,6 +562,7 @@
                       target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
                       memoryMaximumSize="${MEM}">
      <include name="**/org/opends/server/util/SetupUtils.java"/>
        <include name="**/org/opends/server/util/CertificateManager.java"/>
      <include name="**/org/opends/server/util/DynamicConstants.java"/>
      <include name="**/org/opends/server/types/OperatingSystem.java"/>
      <compilerarg value="-Xlint:all" />
opends/resource/FindJavaHome.class
Binary files differ
opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -141,10 +141,17 @@
    {
      public void run()
      {
        // Setup MacOSX native menu bar before AWT is loaded.
        Utils.setMacOSXMenuBar(getFrameTitle());
        SplashScreen.main(args);
        returnValue[0] = 0;
        try
        {
          // Setup MacOSX native menu bar before AWT is loaded.
          Utils.setMacOSXMenuBar(getFrameTitle());
          SplashScreen.main(args);
          returnValue[0] = 0;
        }
        catch (Throwable t)
        {
          t.printStackTrace();
        }
      }
    });
    /*
@@ -152,7 +159,7 @@
     * problems with the display environment.
     */
    PrintStream printStream = System.err;
    System.setErr(new EmptyPrintStream());
    //System.setErr(new EmptyPrintStream());
    t.start();
    try
    {
opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
New file
@@ -0,0 +1,356 @@
/*
 * 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 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
/**
 * Class used to describe the Security Options specified by the user.
 *
 */
public class SecurityOptions
{
  private boolean enableSSL;
  private boolean enableStartTLS;
  private int sslPort = 636;
  /**
   * The different type of security options that we can have.
   */
  public enum CertificateType
  {
    /**
     * No certificate to be used (and so no SSL and no Start TLS).
     */
    NO_CERTIFICATE,
    /**
     * Use a newly created Self Signed Certificate.
     */
    SELF_SIGNED_CERTIFICATE,
    /**
     * Use an existing JKS keystore.
     */
    JKS,
    /**
     * Use an existing PKCS#11 keystore.
     */
    PKCS11,
    /**
     * Use an existing PKCS#12 keystore.
     */
    PKCS12
  }
  private CertificateType certificateType;
  private String selfSignedCertificateName;
  private String keyStorePath;
  private String keyStorePassword;
  private String aliasToUse;
  private SecurityOptions()
  {
  }
  /**
   * Creates a new instance of a SecurityOptions representing for no certificate
   * (no SSL or Start TLS).
   * @return a new instance of a SecurityOptions representing for no certificate
   * (no SSL or Start TLS).
   */
  public static SecurityOptions createNoCertificateOptions()
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.NO_CERTIFICATE);
    ops.setEnableSSL(false);
    ops.setEnableStartTLS(false);
    return ops;
  }
  /**
   * Creates a new instance of a SecurityOptions using a self-signed
   * certificate.
   * @param name the name of the certificate (the CN value).
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @return a new instance of a SecurityOptions using a self-signed
   * certificate.
   */
  public static SecurityOptions createSelfSignedCertificateOptions(String name,
      boolean enableSSL, boolean enableStartTLS, int sslPort)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.SELF_SIGNED_CERTIFICATE);
    ops.setSelfSignedCertificateName(name);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort, null);
    return ops;
  }
  /**
   * Creates a new instance of a SecurityOptions using a Java Key Store.
   * @param keystorePath the path of the key store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a Java Key Store.
   */
  public static SecurityOptions createJKSCertificateOptions(String keystorePath,
      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.JKS);
    ops.setKeyStorePath(keystorePath);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
  }
  /**
   * Creates a new instance of a SecurityOptions using a PKCS#11 Key Store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a PKCS#11 Key Store.
   */
  public static SecurityOptions createPKCS11CertificateOptions(
      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.PKCS11);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
  }
  /**
   * Creates a new instance of a SecurityOptions using a PKCS#12 Key Store.
   * @param keystorePath the path of the key store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a PKCS#12 Key Store.
   */
  public static SecurityOptions createPKCS12CertificateOptions(
      String keystorePath, String keystorePwd, boolean enableSSL,
      boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.PKCS12);
    ops.setKeyStorePath(keystorePath);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
  }
  /**
   * Returns the CertificateType for this instance.
   * @return the CertificateType for this instance.
   */
  public CertificateType getCertificateType()
  {
    return certificateType;
  }
  /**
   * Sets the CertificateType for this instance.
   * @param certificateType the CertificateType for this instance.
   */
  private void setCertificateType(CertificateType certificateType)
  {
    this.certificateType = certificateType;
  }
  /**
   * Returns whether SSL is enabled or not.
   * @return <CODE>true</CODE> if SSL is enabled and <CODE>false</CODE>
   * otherwise.
   */
  public boolean getEnableSSL()
  {
    return enableSSL;
  }
  /**
   * Sets whether SSL is enabled or not.
   * @param enableSSL whether SSL is enabled or not.
   */
  private void setEnableSSL(boolean enableSSL)
  {
    this.enableSSL = enableSSL;
  }
  /**
   * Returns whether StartTLS is enabled or not.
   * @return <CODE>true</CODE> if StartTLS is enabled and <CODE>false</CODE>
   * otherwise.
   */
  public boolean getEnableStartTLS()
  {
    return enableStartTLS;
  }
  /**
   * Sets whether StartTLS is enabled or not.
   * @param enableStartTLS whether StartTLS is enabled or not.
   */
  private void setEnableStartTLS(boolean enableStartTLS)
  {
    this.enableStartTLS = enableStartTLS;
  }
  /**
   * Returns the key store password.
   * @return the key store password.
   */
  public String getKeystorePassword()
  {
    return keyStorePassword;
  }
  /**
   * Sets the key store password.
   * @param keystorePassword the new key store password.
   */
  private void setKeyStorePassword(String keyStorePassword)
  {
    this.keyStorePassword = keyStorePassword;
  }
  /**
   * Returns the key store path.
   * @return the key store path.
   */
  public String getKeystorePath()
  {
    return keyStorePath;
  }
  /**
   * Sets the key store path.
   * @param keyStorePath the new key store path.
   */
  private void setKeyStorePath(String keyStorePath)
  {
    this.keyStorePath = keyStorePath;
  }
  /**
   * Returns the self-signed certificate name.
   * @return the self-signed certificate name.
   */
  public String getSelfSignedCertificateName()
  {
    return selfSignedCertificateName;
  }
  /**
   * Sets the self-signed certificate name.
   * @param selfSignedCertificateName the new self-signed certificate name.
   */
  private void setSelfSignedCertificateName(String selfSignedCertificateName)
  {
    this.selfSignedCertificateName = selfSignedCertificateName;
  }
  /**
   * Updates the provided certificate options object with some parameters.
   * @param ops the SecurityOptions object to be updated.
   * @param enableSSL whether to enable SSL or not.
   * @param enableStartTLS whether to enable StartTLS or not.
   * @param sslPort the LDAPS port number.
   * @param aliasToUse the name of the alias to be used.
   */
  private static void updateCertificateOptions(SecurityOptions ops,
      boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    if (!enableSSL && !enableStartTLS)
    {
      throw new IllegalArgumentException(
          "You must enable SSL or StartTLS to use a certificate.");
    }
    ops.setEnableSSL(enableSSL);
    ops.setEnableStartTLS(enableStartTLS);
    ops.setSslPort(sslPort);
    ops.setAliasToUse(aliasToUse);
  }
  /**
   * Returns the SSL port.
   * @return the SSL port.
   */
  public int getSslPort()
  {
    return sslPort;
  }
  /**
   * Sets the SSL port.
   * @param sslPort the new SSL port.
   */
  void setSslPort(int sslPort)
  {
    this.sslPort = sslPort;
  }
  /**
   * Sets the Self-Signed certificate name (the CN).
   * @param selfSignedCertificateName the new Self-Signed certificate name.
   */
  void setCertificateUserName(String selfSignedCertificateName)
  {
    this.selfSignedCertificateName = selfSignedCertificateName;
  }
  /**
   * Returns the alias of the certificate in the keystore to be used.
   * @return the alias of the certificate in the keystore to be used.
   */
  public String getAliasToUse()
  {
    return aliasToUse;
  }
  /**
   * Sets the certificate alias name.
   * @param aliasToUse the certificate alias name.
   */
  void setAliasToUse(String aliasToUse)
  {
    this.aliasToUse = aliasToUse;
  }
}
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -40,6 +40,7 @@
  private String directoryManagerDn;
  private String directoryManagerPwd;
  private DataOptions dataOptions;
  private SecurityOptions securityOptions;
  private int serverJMXPort;
  private boolean startServer;
  private boolean stopServer;
@@ -63,6 +64,10 @@
    setDirectoryManagerDn("cn=Directory Manager");
    setDataOptions(defaultDataOptions);
    SecurityOptions sec = SecurityOptions.createNoCertificateOptions();
    sec.setSslPort(getDefaultSslPort());
    sec.setCertificateUserName(getDefaultSelfSignedName());
    setSecurityOptions(sec);
  }
  /**
@@ -219,11 +224,34 @@
  }
  /**
   * Returns the SecurityOptions representing the SSL/StartTLS configuration
   * chosen by the user.
   * @return the SecurityOptions representing the SSL/StartTLS configuration
   * chosen by the user.
   */
  public SecurityOptions getSecurityOptions()
  {
    return securityOptions;
  }
  /**
   * Sets the SecurityOptions representing the SSL/StartTLS configuration
   * chosen by the user.
   * @param securityOptions the SecurityOptions representing the SSL/StartTLS
   * configuration chosen by the user.
   */
  public void setSecurityOptions(SecurityOptions securityOptions)
  {
    this.securityOptions = securityOptions;
  }
  /**
   * Provides the port that will be proposed to the user in the second page of
   * the installation wizard. It will check whether we can use 389 and if not it
   * will return -1.
   * the installation wizard. It will check whether we can use ports of type
   * X389 and if not it will return -1.
   *
   * @return the port 389 if it is available and we can use and -1 if not.
   * @return the free port of type x389 if it is available and we can use and -1
   * if not.
   */
  static public int getDefaultPort()
  {
@@ -241,18 +269,50 @@
  }
  /**
   * Provides the port that will be proposed to the user in the security dialog
   *  of the installation wizard. It will check whether we can use ports of type
   * X636 and if not it will return -1.
   *
   * @return the free port of type X636 if it is available and we can use and -1
   * if not.
   */
  static int getDefaultSslPort()
  {
    int defaultPort = -1;
    for (int i=0;i<10000 && (defaultPort == -1);i+=1000)
    {
      int port = i + 636;
      if (Utils.canUseAsPort(port))
      {
        defaultPort = port;
      }
    }
    return defaultPort;
  }
  /**
   * Provides the port that will be used by default for JMX.
   *
   * @param forbiddenPorts an array of ports that we cannot use.
   * @return the port X689 if it is available and we can use and -1 if not.
   */
  static public int getDefaultJMXPort()
  static public int getDefaultJMXPort(int[] forbiddenPorts)
  {
    int defaultJMXPort = -1;
    for (int i=0;i<65000 && (defaultJMXPort == -1);i+=1000)
    {
      int port = i + SetupUtils.getDefaultJMXPort();
      if (Utils.canUseAsPort(port))
      boolean isForbidden = false;
      if (forbiddenPorts != null)
      {
        for (int j=0; j<forbiddenPorts.length && !isForbidden; j++)
        {
          isForbidden = forbiddenPorts[j] == port;
        }
      }
      if (!isForbidden && Utils.canUseAsPort(port))
      {
        defaultJMXPort = port;
      }
@@ -260,4 +320,20 @@
    return defaultJMXPort;
  }
  /**
   * Provides the default name for the self signed certificate that will be
   * created.
   */
  private String getDefaultSelfSignedName()
  {
    String name = "";
    try
    {
      name = java.net.InetAddress.getLocalHost().getHostName();
    }
    catch (Throwable t)
    {
    }
    return name;
  }
}
opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java
@@ -72,7 +72,11 @@
    /**
     * The Browser is used to retrieve an LDIF file.
     */
    OPEN_LDIF_FILE
    OPEN_LDIF_FILE,
    /**
     * The Browser is used to retrieve a generic file.
     */
    GENERIC_FILE
  }
  /**
@@ -117,6 +121,13 @@
      fc.setFileFilter(ldifFiles);
      break;
    case GENERIC_FILE:
      fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
      fc.setDialogType(JFileChooser.OPEN_DIALOG);
      fc.setDialogTitle(i18n.getMsg("open-generic-file-dialog-title"));
      break;
    default:
      throw new IllegalArgumentException("Unknown BrowseType: " + type);
    }
@@ -162,6 +173,10 @@
      returnVal = fc.showOpenDialog(parent);
      break;
    case GENERIC_FILE:
      returnVal = fc.showOpenDialog(parent);
      break;
    default:
      throw new IllegalStateException("Unknown type: " + type);
    }
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -29,16 +29,22 @@
import static org.opends.quicksetup.Step.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.*;
import java.awt.event.WindowEvent;
import org.opends.quicksetup.ui.*;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.*;
import org.opends.server.util.CertificateManager;
import org.opends.quicksetup.installer.ui.InstallReviewPanel;
import org.opends.server.util.SetupUtils;
import javax.naming.ldap.Rdn;
import javax.swing.*;
@@ -66,9 +72,15 @@
  // Constants used to do checks
  private static final int MIN_DIRECTORY_MANAGER_PWD = 1;
  private static final int MIN_PORT_VALUE = 1;
  /**
   * The minimum integer value that can be used for a port.
   */
  public static final int MIN_PORT_VALUE = 1;
  private static final int MAX_PORT_VALUE = 65535;
  /**
   * The maximum integer value that can be used for a port.
   */
  public static final int MAX_PORT_VALUE = 65535;
  private static final int MIN_NUMBER_ENTRIES = 1;
@@ -440,6 +452,65 @@
    argList.add(Utils.getPath(getInstallation().getCurrentConfigurationFile()));
    argList.add("-p");
    argList.add(String.valueOf(getUserData().getServerPort()));
    SecurityOptions sec = getUserData().getSecurityOptions();
    if (sec.getEnableSSL())
    {
      argList.add("-P");
      argList.add(String.valueOf(sec.getSslPort()));
    }
    if (sec.getEnableStartTLS())
    {
      argList.add("-q");
    }
    switch (sec.getCertificateType())
    {
    case SELF_SIGNED_CERTIFICATE:
      argList.add("-k");
      argList.add("cn=JKS,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      break;
    case JKS:
      argList.add("-k");
      argList.add("cn=JKS,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-m");
      argList.add(sec.getKeystorePath());
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      break;
    case PKCS12:
      argList.add("-k");
      argList.add("cn=PKCS12,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      // We are going to import the PCKS12 certificate in a JKS truststore
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-m");
      argList.add(sec.getKeystorePath());
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      break;
    case PKCS11:
      argList.add("-k");
      argList.add("cn=PKCS11,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      // We are going to import the PCKS11 certificate in a JKS truststore
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      break;
    case NO_CERTIFICATE:
      // Nothing to do.
      break;
    default:
      throw new IllegalStateException("Unknown certificate type: "+
          sec.getCertificateType());
    }
    argList.add("-x");
    argList.add(String.valueOf(getUserData().getServerJMXPort()));
@@ -471,6 +542,113 @@
          QuickSetupException.Type.CONFIGURATION_ERROR,
          getThrowableMsg("error-configuring", null, t), t);
    }
    try
    {
      SecurityOptions.CertificateType certType = sec.getCertificateType();
      if (certType != SecurityOptions.CertificateType.NO_CERTIFICATE)
      {
        notifyListeners(getLineBreak());
        notifyListeners(getFormattedWithPoints(
            getMsg("progress-updating-certificates")));
      }
      CertificateManager certManager;
      CertificateManager trustManager;
      File f;
      switch (certType)
      {
      case NO_CERTIFICATE:
        // Nothing to do
        break;
      case SELF_SIGNED_CERTIFICATE:
        String pwd = getSelfSignedCertificatePwd();
        certManager = new CertificateManager(
            getSelfSignedKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            pwd);
        certManager.generateSelfSignedCertificate("server-cert",
            getSelfSignedCertificateSubjectDN(sec),
            getSelfSignedCertificateValidity());
        exportCertificate(certManager, "server-cert",
            getTemporaryCertificatePath());
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            pwd);
        trustManager.addCertificate("server-cert",
            new File(getTemporaryCertificatePath()));
        Utils.createFile(getKeystorePinPath(), pwd);
        f = new File(getTemporaryCertificatePath());
        f.delete();
        break;
      case JKS:
        certManager = new CertificateManager(
            sec.getKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
            new File(getTemporaryCertificatePath()));
        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
        f = new File(getTemporaryCertificatePath());
        f.delete();
        break;
      case PKCS12:
        certManager = new CertificateManager(
            sec.getKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_PKCS12,
            sec.getKeystorePassword());
        exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
            new File(getTemporaryCertificatePath()));
        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
        f = new File(getTemporaryCertificatePath());
        f.delete();
        break;
      case PKCS11:
        certManager = new CertificateManager(
            CertificateManager.KEY_STORE_PATH_PKCS11,
            CertificateManager.KEY_STORE_TYPE_PKCS11,
            sec.getKeystorePassword());
        exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
            new File(getTemporaryCertificatePath()));
        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
        break;
      default:
        throw new IllegalStateException("Unknown certificate type: "+certType);
      }
      if (certType != SecurityOptions.CertificateType.NO_CERTIFICATE)
      {
        notifyListeners(getFormattedDone());
      }
    }
    catch (Throwable t)
    {
      throw new QuickSetupException(
          QuickSetupException.Type.CONFIGURATION_ERROR,
          getThrowableMsg("error-configuring-certificate", null, t), t);
    }
  }
  /**
@@ -535,7 +713,7 @@
    String[] arg =
      { getUserData().getDataOptions().getLDIFPath() };
    notifyListeners(getFormattedProgress(getMsg("progress-importing-ldif", arg))
        + formatter.getLineBreak());
        + getLineBreak());
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
@@ -582,7 +760,7 @@
      { String.valueOf(nEntries) };
    notifyListeners(getFormattedProgress(getMsg(
        "progress-import-automatically-generated", arg))
        + formatter.getLineBreak());
        + getLineBreak());
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
@@ -783,9 +961,10 @@
    // Check the port
    String sPort = qs.getFieldStringValue(FieldName.SERVER_PORT);
    int port = -1;
    try
    {
      int port = Integer.parseInt(sPort);
      port = Integer.parseInt(sPort);
      if ((port < MIN_PORT_VALUE) || (port > MAX_PORT_VALUE))
      {
        String[] args =
@@ -819,6 +998,52 @@
      qs.displayFieldInvalid(FieldName.SERVER_PORT, true);
    }
    // Check the secure port
    SecurityOptions sec =
      (SecurityOptions)qs.getFieldValue(FieldName.SECURITY_OPTIONS);
    int securePort = sec.getSslPort();
    if (sec.getEnableSSL())
    {
      if ((securePort < MIN_PORT_VALUE) || (securePort > MAX_PORT_VALUE))
      {
        String[] args =
          { String.valueOf(MIN_PORT_VALUE), String.valueOf(MAX_PORT_VALUE) };
        errorMsgs.add(getMsg("invalid-secure-port-value-range", args));
        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
      } else if (!Utils.canUseAsPort(securePort))
      {
        if (Utils.isPriviledgedPort(securePort))
        {
          errorMsgs.add(getMsg("cannot-bind-priviledged-port", new String[]
            { String.valueOf(securePort) }));
        } else
        {
          errorMsgs.add(getMsg("cannot-bind-port", new String[]
            { String.valueOf(securePort) }));
        }
        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
      }
      else if (port == securePort)
      {
        errorMsgs.add(getMsg("equal-ports",
            new String[] { String.valueOf(securePort) }));
        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
        qs.displayFieldInvalid(FieldName.SERVER_PORT, true);
      }
      else
      {
        getUserData().setSecurityOptions(sec);
        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, false);
      }
    }
    else
    {
      getUserData().setSecurityOptions(sec);
      qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, false);
    }
    // Check the Directory Manager DN
    String dmDn = qs.getFieldStringValue(FieldName.DIRECTORY_MANAGER_DN);
@@ -876,7 +1101,8 @@
      qs.displayFieldInvalid(FieldName.DIRECTORY_MANAGER_PWD_CONFIRM, false);
    }
    int defaultJMXPort = UserData.getDefaultJMXPort();
    int defaultJMXPort =
      UserData.getDefaultJMXPort(new int[] {port, securePort});
    if (defaultJMXPort != -1)
    {
      getUserData().setServerJMXPort(defaultJMXPort);
@@ -1035,4 +1261,156 @@
    return 15 * 1024 * 1024;
  }
  /**
   * Returns the keystore path to be used for generating a self-signed
   * certificate.
   * @return the keystore path to be used for generating a self-signed
   * certificate.
   */
  private String getSelfSignedKeystorePath()
  {
    String parentFile = Utils.getPath(getInstallationPath(),
        Installation.CONFIG_PATH_RELATIVE);
    return (Utils.getPath(parentFile, "keystore"));
  }
  /**
   * Returns the trustmanager path to be used for generating a self-signed
   * certificate.
   * @return the trustmanager path to be used for generating a self-signed
   * certificate.
   */
  private String getTrustManagerPath()
  {
    String parentFile = Utils.getPath(getInstallationPath(),
        Installation.CONFIG_PATH_RELATIVE);
    return (Utils.getPath(parentFile, "truststore"));
  }
  /**
   * Returns the path of the self-signed that we export to be able to create
   * a truststore.
   * @return the path of the self-signed that is exported.
   */
  private String getTemporaryCertificatePath()
  {
    String parentFile = Utils.getPath(getInstallationPath(),
        Installation.CONFIG_PATH_RELATIVE);
    return (Utils.getPath(parentFile, "server-cert.txt"));
  }
  /**
   * Returns the path to be used to store the password of the keystore.
   * @return the path to be used to store the password of the keystore.
   */
  private String getKeystorePinPath()
  {
    String parentFile = Utils.getPath(getInstallationPath(),
        Installation.CONFIG_PATH_RELATIVE);
    return (Utils.getPath(parentFile, "keystore.pin"));
  }
  /**
   * Returns the validity period to be used to generate the self-signed
   * certificate.
   * @return the validity period to be used to generate the self-signed
   * certificate.
   */
  private int getSelfSignedCertificateValidity()
  {
    return 2 * 365;
  }
  /**
   * Returns the Subject DN to be used to generate the self-signed certificate.
   * @return the Subject DN to be used to generate the self-signed certificate.
   */
  private String getSelfSignedCertificateSubjectDN(SecurityOptions sec)
  {
    return "cn="+Rdn.escapeValue(sec.getSelfSignedCertificateName())+
    ",O=OpenDS Self-Signed Certificate";
  }
  /**
   * Returns a randomly generated password for the self-signed certificate
   * keystore.
   * @return a randomly generated password for the self-signed certificate
   * keystore.
   */
  private String getSelfSignedCertificatePwd()
  {
    int pwdLength = 50;
    char[] pwd = new char[pwdLength];
    Random random = new Random();
    for (int pos=0; pos < pwdLength; pos++) {
        int type = getRandomInt(random,3);
        char nextChar = getRandomChar(random,type);
        pwd[pos] = nextChar;
    }
    String pwdString = new String(pwd);
    return pwdString;
  }
  private void exportCertificate(CertificateManager certManager, String alias,
      String path) throws CertificateEncodingException, IOException,
      KeyStoreException
  {
    Certificate certificate = certManager.getCertificate(alias);
    byte[] certificateBytes = certificate.getEncoded();
    FileOutputStream outputStream = new FileOutputStream(path, false);
    outputStream.write(certificateBytes);
    outputStream.close();
  }
  /* The next two methods are used to generate the random password for the
   * self-signed certificate. */
  private char getRandomChar(Random random, int type)
  {
    char generatedChar;
    int next = random.nextInt();
    int d;
    switch (type)
    {
    case 0:
      // Will return a figure
      d = next % 10;
      if (d < 0)
      {
        d = d * (-1);
      }
      generatedChar = (char) (d+48);
      break;
    case 1:
      // Will return a lower case letter
      d = next % 26;
      if (d < 0)
      {
        d = d * (-1);
      }
      generatedChar =  (char) (d + 97);
      break;
    default:
      // Will return a capital letter
      d = (next % 26);
      if (d < 0)
      {
        d = d * (-1);
      }
      generatedChar = (char) (d + 65) ;
    }
    return generatedChar;
  }
  private static int getRandomInt(Random random,int modulo)
  {
    int value = 0;
    value = (random.nextInt() & modulo);
    return value;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -73,8 +73,10 @@
    {
      setFieldValue(FieldName.SERVER_LOCATION, userData.getServerLocation());
    }
    setFieldValue(FieldName.SERVER_PORT, String.valueOf(userData
        .getServerPort()));
    setFieldValue(FieldName.SERVER_PORT,
        String.valueOf(userData.getServerPort()));
    setFieldValue(FieldName.SECURITY_OPTIONS,
        getSecurityOptionsString(userData.getSecurityOptions(), false));
    setFieldValue(FieldName.DIRECTORY_MANAGER_DN, userData
        .getDirectoryManagerDn());
    setFieldValue(FieldName.DIRECTORY_BASE_DN, userData.getDataOptions()
@@ -133,6 +135,11 @@
        LabelFieldDescriptor.FieldType.READ_ONLY,
        LabelFieldDescriptor.LabelType.PRIMARY, 0));
    hm.put(FieldName.SECURITY_OPTIONS, new LabelFieldDescriptor(
        getMsg("server-security-label"), getMsg("server-security-tooltip"),
        LabelFieldDescriptor.FieldType.READ_ONLY,
        LabelFieldDescriptor.LabelType.PRIMARY, 0));
    hm.put(FieldName.DIRECTORY_MANAGER_DN, new LabelFieldDescriptor(
        getMsg("server-directory-manager-dn-label"),
        getMsg("server-directory-manager-dn-tooltip"),
@@ -248,17 +255,23 @@
    if (displayServerLocation)
    {
      fieldNames =
          new FieldName[]
            { FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
                FieldName.DIRECTORY_MANAGER_DN,
                FieldName.DIRECTORY_BASE_DN,
                FieldName.DATA_OPTIONS };
    } else
        new FieldName[]
          {
            FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
            FieldName.SECURITY_OPTIONS, FieldName.DIRECTORY_MANAGER_DN,
            FieldName.DIRECTORY_BASE_DN,
            FieldName.DATA_OPTIONS
          };
    }
    else
    {
      fieldNames =
          new FieldName[]
            { FieldName.SERVER_PORT, FieldName.DIRECTORY_MANAGER_DN,
                FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS };
        new FieldName[]
          {
            FieldName.SERVER_PORT, FieldName.SECURITY_OPTIONS,
            FieldName.DIRECTORY_MANAGER_DN,
            FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS
          };
    }
    for (int i = 0; i < fieldNames.length; i++)
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -284,11 +284,14 @@
least {1} megabytes of free disk space are required to install OpenDS.
invalid-port-value-range=The LDAP Listener Port must be an integer between \
{0} and {1}.
invalid-secure-port-value-range=The LDAPS Listener Port must be an \
integer between {0} and {1}.
cannot-bind-priviledged-port=Cannot bind to privileged port {0}.\n\nThe port \
could be already in use by another application or maybe you do not have the \
rights to access it.
cannot-bind-port=Cannot bind to port {0}.\n\nThe port could be already in use \
by another application or maybe you do not have the rights to access it.
equal-ports=You must specify different ports LDAP and LDAPS communication.
empty-directory-manager-dn=You must provide an Administrative User DN.
not-a-directory-manager-dn=The provided Administrative User DN is not a valid \
DN.
@@ -428,6 +431,13 @@
server-port-label=LDAP Listener Port:
server-port-tooltip=Enter the port number that the server will use to listen \
for LDAP requests
server-security-label=LDAP Secure Access:
server-security-tooltip=The LDAP Secure Access Configuration for the new \
OpenDS server.
cannot-update-security-warning=Disabled.  A valid keytool command could not be \
found.
server-security-button-label=Configure...
server-security-button-tooltip=Click to configure the LDAP Secure Access.
server-directory-manager-dn-label=Administrative User DN:
server-directory-manager-dn-tooltip=Enter the distinguished name (DN) of the \
Administrative User account that will used for managing OpenDS
@@ -438,6 +448,91 @@
server-directory-manager-pwd-confirm-tooltip=Re-enter the password for the \
OpenDS Administrative User account
cannot-use-default-port=Could not use 389. Port in use or user not authorized.
cannot-use-default-secure-port=Could not use 636. Port in use or user not \
authorized.
no-security=disabled
enable-starttls=Enable StartTLS
enable-ssl=Enable SSL on LDAP Port {0}
self-signed-certificate=Create a new Self-Signed Certificate
jks-certificate=Use existing Java Key Store File
pkcs11-certificate=Use existing PKCS#11 Token
pkcs12-certificate=Use existing PKCS#12 File
#
# Security Options dialog specific labels
#
security-options-dialog-title=OpenDS QuickSetup
security-options-title=Configure Secure Access
security-options-instructions=Specify the options for enabling secure access \
to the server.
security-options-ok-button-tooltip=Close this dialog and accept configuration.
security-options-cancel-button-tooltip=Close this dialog and discard \
configuration.
enable-ssl-label=Enable SSL on Port:
enable-ssl-tooltip=Enables SSL on the specified port.
ssl-port-textfield-tooltip=The LDAPS port.
enable-starttls-label=Enable StartTLS for LDAP
enable-starttls-tooltip=Allows encrypted communication over the standard \
LDAP port.
use-self-signed-label=Generate Self-Signed Certificate (recommended for \
testing only)
use-self-signed-tooltip=Create a new Self-Signed Certificate to encrypt \
communication.
self-signed-certificate-name-label=Host Name:
self-signed-certificate-name-tooltip=The host name will be used to name the \
certificate.
use-existing-certificate-label=Use an Existing Certificate:
use-existing-certificate-tooltip=Select this if you have already a certificate \
you want the new server to use.
keystore-type-label=Key Store Type:
jks-certificate-label=Java Key Store (JKS) File
jks-certificate-tooltip=Select this option if you have a JKS certificate.
pkcs11-certificate-label=PKCS#11 Token
pkcs11-certificate-tooltip=Select this option if you have a PKCS#11 token.
pkcs12-certificate-label=PKCS#12 File
pkcs12-certificate-tooltip=Select this option if you have a PKCS#12 certificate.
keystore-path-label=Key Store Path:
keystore-path-tooltip=Absolute path to the keystore.
keystore-pwd-label=Key Store Password:
keystore-pwd-tooltip=Provide the password required to access the existing \
key store.
ssl-access-label=SSL Access:
starttls-access-label=StartTLS Access:
certificate-label=Certificate:
no-self-signed-cert-name-provided=You must provide the host name for the \
Self-Signed Certificate.
keystore-path-not-provided=You must provide the path of the key store.
keystore-path-does-not-exist=The provided key store path does not exist.
keystore-path-not-a-file=The provided key store path is not a file.
keystore-pwd-empty=You must provide the password of the key store.
error-accessing-jks-keystore=Could not access the JKS key store.  Check that \
the contents of the file\ncorrespond to a valid JKS key store, that you have \
access rights to it and\nthat the provided password is valid.
error-accessing-pkcs11-keystore=Could not access the PKCS#11 key store.  Check \
that is installed and that the\nprovided password is valid.
error-accessing-pkcs12-keystore=Could not access the PKCS#12 key store.  Check \
that the contents of the file\ncorrespond to a valid PKCS#12 key store, that \
you have access rights to it and\nthat the provided password is valid.
pkcs11-keystore-does-not-exist=No certificates for the PCKS#11 key store could \
be found.  Check that is\ninstalled, that you have access rights to it and \
that the key store contains certificates.
pkcs12-keystore-does-not-exist=No certificates for the PCKS#12 key store could \
be found.  Check that the\nprovided path and password are valid and that the \
key store contains certificates.
jks-keystore-does-not-exist=No certificates for the Java Key Store could be \
found.  Check that the provided\npath is valid.
#
# Select Alias dialog specific labels
#
select-alias-title=OpenDS QuickSetup
select-alias-msg=The provided Key Store contains multiple certificates.<br>\
Select the alias of the certificate that you want to be used as Server \
Certificate:
select-alias-ok-button-tooltip=Close this dialog and accept \
selected alias.
select-alias-cancel-button-tooltip=Close this dialog and discard \
selected alias.
#
# Data Options Panel specific labels
@@ -531,9 +626,10 @@
#
browse-button-label=Browse...
browse-button-tooltip=Click to display a file system browser
ldif-files-description=Lightweight Directory Interchange Format (*.ldif)
ldif-files-description=LDAP Data Interchange Format (*.ldif)
open-server-location-dialog-title=Choose Installation Path
open-ldif-file-dialog-title=Choose an LDIF File
open-generic-file-dialog-title=Choose a File
#
# Progress Summary Labels
@@ -608,6 +704,7 @@
progress-points=.....
progress-extracting=Extracting {0}
progress-configuring=Configuring Directory Server
progress-updating-certificates=Configuring Certificates
downloading-ratio=Downloading: {0}% Completed.
validating-ratio=Downloading: {0}% Completed - Validating file: {1} % Completed.
upgrading-ratio=Downloading: {0}% Completed - Upgrading file: {1} % Completed.
@@ -648,6 +745,7 @@
error-creating-temp-file=An error occurred creating the temporary file.
error-writing-to-temp-file=An error occurred writing to temporary file {0}.
error-configuring=Error Configuring Directory Server.
error-configuring-certificate=Error Configuring Certificates.
error-enabling-windows-service=Error Enabling Windows service.
error-disabling-windows-service=Error Disabling Windows service.
error-creating-base-entry=Error Creating Base Entry.
opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
@@ -187,9 +187,13 @@
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    panel.add(auxPanel, gbc);
    int h1 = getLabel(FieldName.DATA_OPTIONS).getPreferredSize().height;
    int h2 = getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY).
    getPreferredSize().height;
    int additionalInset = Math.abs(h2 - h1) / 2;
    gbc.gridwidth = GridBagConstraints.RELATIVE;
    gbc.weightx = 0.0;
    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD + additionalInset;
    gbc.insets.left = 0;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    panel.add(getLabel(FieldName.DATA_OPTIONS), gbc);
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
@@ -357,7 +357,7 @@
        } catch (NamingException ne)
        {
          if (installStatus.isServerRunning())
          if (CurrentInstallStatus.isServerRunning())
          {
            throw ne;
          }
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -64,6 +64,10 @@
   */
  DIRECTORY_BASE_DN, // the value associated with this is a String
  /**
  * The value associated with this is a SecurityOptions object.
  */
  SECURITY_OPTIONS,
  /**
   * The value associated with this is a DataOptions.Type.
   */
  DATA_OPTIONS,
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -44,6 +44,7 @@
import org.opends.quicksetup.event.ButtonActionListener;
import org.opends.quicksetup.event.ButtonEvent;
import org.opends.quicksetup.ProgressDescriptor;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.util.HtmlProgressMessageFormatter;
import org.opends.quicksetup.util.ProgressMessageFormatter;
@@ -391,6 +392,91 @@
  }
  /**
   * Returns a localized String representation of the provided SecurityOptions
   * object.
   * @param ops the SecurityOptions object from which we want to obtain the
   * String representation.
   * @param html whether the resulting String must be in HTML or not.
   * @return a localized String representation of the provided SecurityOptions
   * object.
   */
  protected String getSecurityOptionsString(SecurityOptions ops, boolean html)
  {
    StringBuilder buf = new StringBuilder();
    if (ops.getCertificateType() ==
      SecurityOptions.CertificateType.NO_CERTIFICATE)
    {
      buf.append(getMsg("no-security"));
    }
    else
    {
      if (ops.getEnableStartTLS())
      {
        buf.append(getMsg("enable-starttls"));
      }
      if (ops.getEnableSSL())
      {
        if (buf.length() > 0)
        {
          if (html)
          {
            buf.append("<br>");
          }
          else
          {
            buf.append("\n");
          }
        }
        String[] arg = new String[] {String.valueOf(ops.getSslPort())};
        buf.append(getMsg("enable-ssl", arg));
      }
      if (html)
      {
        buf.append("<br>");
      }
      else
      {
        buf.append("\n");
      }
      String certMsg;
      switch (ops.getCertificateType())
      {
      case SELF_SIGNED_CERTIFICATE:
        certMsg = getMsg("self-signed-certificate");
        break;
      case JKS:
        certMsg = getMsg("jks-certificate");
        break;
      case PKCS11:
        certMsg = getMsg("pkcs11-certificate");
        break;
      case PKCS12:
        certMsg = getMsg("pkcs12-certificate");
        break;
      default:
        throw new IllegalStateException("Unknown certificate options type: "+
            ops.getCertificateType());
      }
      buf.append(certMsg);
    }
    if (html)
    {
      return "<html>"+UIFactory.applyFontToHtml(buf.toString(),
          UIFactory.SECONDARY_FIELD_VALID_FONT);
    }
    else
    {
      return buf.toString();
    }
  }
  /**
   * Creates and returns the title panel.
   * @return the title panel.
   */
opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
New file
@@ -0,0 +1,1188 @@
/*
 * 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.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.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);
    UIFactory.IconType ic;
    if (Utils.isMacOS())
    {
      ic = UIFactory.IconType.MINIMIZED_MAC;
    }
    else
    {
      ic = UIFactory.IconType.MINIMIZED;
    }
    setIconImage(UIFactory.getImageIcon(ic).getImage());
    Utils.centerOnComponent(this, parent);
  }
  /**
   * Returns <CODE>true</CODE> if the user clicked on cancel and
   * <CODE>false</CODE> otherwise.
   * @return <CODE>true</CODE> if the user clicked on cancel and
   * <CODE>false</CODE> 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);
    cbEnableSSL.setOpaque(false);
    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);
    cbEnableStartTLS.setOpaque(false);
    rbUseSelfSignedCertificate = UIFactory.makeJRadioButton(
        getMsg("use-self-signed-label"),
        getMsg("use-self-signed-tooltip"),
        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbUseSelfSignedCertificate.setOpaque(false);
    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.setOpaque(false);
    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.setOpaque(false);
    rbJKS.addActionListener(l);
    rbPKCS11 = UIFactory.makeJRadioButton(
        getMsg("pkcs11-certificate-label"),
        getMsg("pkcs11-certificate-tooltip"),
        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbPKCS11.setOpaque(false);
    rbPKCS11.addActionListener(l);
    rbPKCS12 = UIFactory.makeJRadioButton(
        getMsg("pkcs12-certificate-label"),
        getMsg("pkcs12-certificate-tooltip"),
        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbPKCS12.setOpaque(false);
    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<String> errorMsgs = new ArrayList<String>();
        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<String> errorMsgs = new ArrayList<String>();
            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<String> checkPort()
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    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<String> checkSelfSigned()
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    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<String> checkKeystore()
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    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();
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
New file
@@ -0,0 +1,275 @@
/*
 * 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 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
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.util.TreeSet;
import javax.swing.Box;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.util.Utils;
/**
 * This class is a dialog that appears when the user must choose the alias to
 * be used from a certificate keystore.
 */
public class SelectAliasDialog extends JDialog
{
  private JButton okButton;
  private JComboBox comboAliases;
  private boolean isCancelled;
  private static final long serialVersionUID = -8140704273612764046L;
  /**
   * Constructor of the SelectAliasDialog.
   * @param parent the parent frame for this dialog.
   */
  public SelectAliasDialog(JDialog parent)
  {
    super(parent);
    setTitle(getMsg("select-alias-title"));
    getContentPane().add(createPanel());
    pack();
    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);
    setModal(true);
  }
  /**
   * Displays this dialog with the provided aliases.
   *
   * @param aliases the aliases to display.
   */
  public void display(String[] aliases)
  {
    if ((aliases == null) || (aliases.length ==0))
    {
      throw new IllegalArgumentException(
          "The provided aliases are null or empty.");
    }
    isCancelled = true;
    TreeSet<String> s = new TreeSet<String>();
    for (int i=0; i<aliases.length; i++)
    {
      s.add(aliases[i]);
    }
    String[] orderedAliases = new String[s.size()];
    s.toArray(orderedAliases);
    comboAliases.setModel(new DefaultComboBoxModel(orderedAliases));
    comboAliases.setSelectedIndex(0);
    setVisible(true);
  }
  /**
   * Returns <CODE>true</CODE> if the user clicked on cancel and
   * <CODE>false</CODE> otherwise.
   * @return <CODE>true</CODE> if the user clicked on cancel and
   * <CODE>false</CODE> otherwise.
   */
  public boolean isCancelled()
  {
    return isCancelled;
  }
  /**
   * Returns the selected certificate alias.
   * @return the selected certificate alias.
   */
  public String getSelectedAlias()
  {
    return (String) comboAliases.getSelectedItem();
  }
  /* The following three methods are just commodity methods to retrieve
   * localized messages */
  private String getMsg(String key)
  {
    return getI18n().getMsg(key);
  }
  private ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
  /**
   * Creates and returns the panel of the dialog.
   * @return the panel of the dialog.
   */
  private JPanel createPanel()
  {
    JPanel p1 = new JPanel(new GridBagLayout());
    p1.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
    p1.setBorder(UIFactory.DIALOG_PANEL_BORDER);
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridwidth = GridBagConstraints.RELATIVE;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    Insets currentStepInsets = UIFactory.getCurrentStepPanelInsets();
    gbc.insets.top = currentStepInsets.top;
    gbc.insets.left = currentStepInsets.left;
    p1.add(UIFactory.makeJLabel(UIFactory.IconType.INFORMATION_LARGE, null,
        UIFactory.TextStyle.NO_STYLE), gbc);
    gbc.weightx = 1.0;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
    gbc.fill = GridBagConstraints.BOTH;
    String msg = getMsg("select-alias-msg");
    JTextComponent tf = UIFactory.makeHtmlPane(msg,
            UIFactory.INSTRUCTIONS_FONT);
    tf.setOpaque(false);
    tf.setEditable(false);
    p1.add(tf, gbc);
    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
    gbc.insets.left = currentStepInsets.left;
    gbc.insets.right = currentStepInsets.right;
    gbc.insets.bottom = currentStepInsets.bottom;
    comboAliases = new JComboBox();
    comboAliases.setPrototypeDisplayValue("The prototype alias name");
    gbc.fill = GridBagConstraints.NONE;
    p1.add(comboAliases, gbc);
    gbc.insets = UIFactory.getEmptyInsets();
    gbc.weighty = 1.0;
    gbc.fill = GridBagConstraints.VERTICAL;
    p1.add(Box.createVerticalGlue(), gbc);
    JPanel p2 = new JPanel(new GridBagLayout());
    p2.setOpaque(false);
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1.0;
    gbc.gridwidth = 3;
    p2.add(Box.createHorizontalGlue(), gbc);
    okButton = UIFactory.makeJButton(getMsg("ok-button-label"),
          getMsg("select-alias-ok-button-tooltip"));
    okButton.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent ev)
      {
        okClicked();
      }
    });
    gbc.fill = GridBagConstraints.NONE;
    gbc.weightx = 0.0;
    gbc.gridwidth = GridBagConstraints.RELATIVE;
    p2.add(okButton, gbc);
    JButton cancelButton = UIFactory.makeJButton(getMsg("cancel-button-label"),
            getMsg("select-alias-cancel-button-tooltip"));
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
    p2.add(cancelButton, gbc);
    cancelButton.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent ev)
      {
        cancelClicked();
      }
    });
    JPanel p = new JPanel(new GridBagLayout());
    p.setBackground(UIFactory.DEFAULT_BACKGROUND);
    gbc.insets = UIFactory.getEmptyInsets();
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.weightx = 1.0;
    gbc.weighty = 1.0;
    p.add(p1, gbc);
    gbc.weighty = 0.0;
    gbc.insets = UIFactory.getButtonsPanelInsets();
    p.add(p2, gbc);
    return p;
  }
  /**
   * Method called when user clicks on cancel.
   *
   */
  private void cancelClicked()
  {
    isCancelled = true;
    dispose();
  }
  /**
   * Method called when user clicks on OK.
   *
   */
  private void okClicked()
  {
    isCancelled = false;
    dispose();
  }
  /**
   * 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();
      SelectAliasDialog dlg =
          new SelectAliasDialog(new JDialog());
      dlg.display(new String[] {"test1", "test2"});
    } catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
@@ -30,6 +30,8 @@
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
@@ -37,12 +39,14 @@
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.event.BrowseActionListener;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.UserData;
/**
@@ -56,10 +60,18 @@
  private Component lastFocusComponent;
  private JLabel lSecurity;
  private JButton secureAccessButton;
  private JButton browseButton;
  private boolean displayServerLocation;
  private boolean canUpdateSecurity;
  private SecurityOptions securityOptions;
  private HashMap<FieldName, JLabel> hmLabels =
      new HashMap<FieldName, JLabel>();
@@ -72,6 +84,8 @@
  private JLabel lServerLocation;
  private SecurityOptionsDialog dlg;
  private static final long serialVersionUID = -15911406930993035L;
  /**
@@ -84,6 +98,9 @@
    super(application);
    this.defaultUserData = application.getUserData();
    this.displayServerLocation = isWebStart();
    canUpdateSecurity =
      org.opends.server.util.CertificateManager.mayUseCertificateManager();
    securityOptions = defaultUserData.getSecurityOptions();
    populateLabelAndFieldMaps();
    addFocusListeners();
  }
@@ -114,7 +131,12 @@
        }
      }
    } else
    }
    else if (fieldName == FieldName.SECURITY_OPTIONS)
    {
      value = securityOptions;
    }
    else
    {
      JTextComponent field = getField(fieldName);
      if (field != null)
@@ -157,9 +179,13 @@
    GridBagConstraints gbc = new GridBagConstraints();
    FieldName[] fieldNames =
          { FieldName.SERVER_PORT, FieldName.DIRECTORY_MANAGER_DN,
              FieldName.DIRECTORY_MANAGER_PWD,
              FieldName.DIRECTORY_MANAGER_PWD_CONFIRM };
    {
        FieldName.SERVER_PORT,
        FieldName.SECURITY_OPTIONS,
        FieldName.DIRECTORY_MANAGER_DN,
        FieldName.DIRECTORY_MANAGER_PWD,
        FieldName.DIRECTORY_MANAGER_PWD_CONFIRM
    };
    JPanel auxPanel;
    // Add the server location widgets
@@ -211,7 +237,21 @@
      gbc.weightx = 0.0;
      gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
      gbc.insets.left = 0;
      gbc.anchor = GridBagConstraints.WEST;
      boolean isSecurityField = fieldName == FieldName.SECURITY_OPTIONS;
      int securityInsetsTop = Math.abs(
          getLDAPSecureAccessButton().getPreferredSize().height -
          getLabel(fieldName).getPreferredSize().height) / 2;
      if (isSecurityField)
      {
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.insets.top += securityInsetsTop;
      }
      else
      {
        gbc.anchor = GridBagConstraints.WEST;
      }
      panel.add(getLabel(fieldName), gbc);
      auxPanel = new JPanel(new GridBagLayout());
@@ -221,18 +261,41 @@
      gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      panel.add(auxPanel, gbc);
      boolean isPortField = fieldName == FieldName.SERVER_PORT;
      gbc.insets = UIFactory.getEmptyInsets();
      if (isPortField) {
      if (isPortField || (isSecurityField && canUpdateSecurity))
      {
        gbc.gridwidth = 3;
      } else {
      }
      else
      {
        gbc.gridwidth = GridBagConstraints.RELATIVE;
      }
      gbc.weightx = 0.0;
      auxPanel.add(getField(fieldName), gbc);
      if (isPortField) {
      if (isSecurityField)
      {
        gbc.insets.top = securityInsetsTop;
        if (canUpdateSecurity)
        {
          auxPanel.add(lSecurity, gbc);
        }
        else
        {
          auxPanel.add(UIFactory.makeJLabel(UIFactory.IconType.WARNING,
              getMsg("cannot-update-security-warning"),
              UIFactory.TextStyle.SECONDARY_FIELD_VALID), gbc);
        }
      }
      else
      {
        auxPanel.add(getField(fieldName), gbc);
      }
      if (isPortField)
      {
        JLabel l =
                UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
                        getPortHelpMessage(),
@@ -241,9 +304,17 @@
        gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
        auxPanel.add(l, gbc);
      }
      else if (isSecurityField && canUpdateSecurity)
      {
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        gbc.insets.left = UIFactory.LEFT_INSET_BROWSE;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.insets.top = 0;
        auxPanel.add(getLDAPSecureAccessButton(), gbc);
      }
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      auxPanel.add(Box.createHorizontalGlue(), gbc);
    }
    addVerticalGlue(panel);
@@ -304,7 +375,8 @@
      if (defaultUserData.getServerPort() > 0)
      {
        value = String.valueOf(defaultUserData.getServerPort());
      } else
      }
      else
      {
        value = "";
      }
@@ -322,6 +394,11 @@
      value = defaultUserData.getDirectoryManagerPwd();
      break;
    case SECURITY_OPTIONS:
      value = getSecurityOptionsString(defaultUserData.getSecurityOptions(),
          true);
      break;
    default:
      throw new IllegalArgumentException("Unknown field name: " +
          fieldName);
@@ -343,6 +420,11 @@
        LabelFieldDescriptor.FieldType.TEXTFIELD,
        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PORT_FIELD_SIZE));
    hm.put(FieldName.SECURITY_OPTIONS, new LabelFieldDescriptor(
        getMsg("server-security-label"), getMsg("server-security-tooltip"),
        LabelFieldDescriptor.FieldType.READ_ONLY,
        LabelFieldDescriptor.LabelType.PRIMARY, 0));
    hm.put(FieldName.DIRECTORY_MANAGER_DN, new LabelFieldDescriptor(
        getMsg("server-directory-manager-dn-label"),
        getMsg("server-directory-manager-dn-tooltip"),
@@ -367,11 +449,20 @@
    {
      LabelFieldDescriptor desc = hm.get(fieldName);
      String defaultValue = getDefaultValue(fieldName);
      JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
      JLabel label = makeJLabel(desc);
      hmFields.put(fieldName, field);
      label.setLabelFor(field);
      if (fieldName != FieldName.SECURITY_OPTIONS)
      {
        JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
        hmFields.put(fieldName, field);
        label.setLabelFor(field);
      }
      else
      {
        lSecurity = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
            defaultValue, UIFactory.TextStyle.SECONDARY_FIELD_VALID);
      }
      hmLabels.put(fieldName, label);
    }
@@ -431,6 +522,36 @@
  }
  /**
   * Returns the configure secure access button.
   * If it does not exist creates the secure access button.
   * @return the secure access button.
   */
  private JButton getLDAPSecureAccessButton()
  {
    if (secureAccessButton == null)
    {
      secureAccessButton =
          UIFactory.makeJButton(getMsg("server-security-button-label"),
              getMsg("server-security-button-tooltip"));
      secureAccessButton.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ev)
        {
          getConfigureSecureAccessDialog().display(securityOptions);
          if (!getConfigureSecureAccessDialog().isCancelled())
          {
            securityOptions =
              getConfigureSecureAccessDialog().getSecurityOptions();
            lSecurity.setText(getSecurityOptionsString(securityOptions, true));
          }
        }
      });
    }
    return secureAccessButton;
  }
  /**
   * Returns the label associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the JLabel.
   * @return the label associated with the given field name.
@@ -472,6 +593,7 @@
    {
      tf.addFocusListener(l);
    }
    getLDAPSecureAccessButton().addFocusListener(l);
    getBrowseButton().addFocusListener(l);
    if (Utils.isWebStart())
    {
@@ -498,4 +620,14 @@
    }
    return s;
  }
  private SecurityOptionsDialog getConfigureSecureAccessDialog()
  {
    if (dlg == null)
    {
      dlg = new SecurityOptionsDialog((JFrame)getMainWindow(), securityOptions);
      dlg.setModal(true);
    }
    return dlg;
  }
}
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -38,7 +38,6 @@
import java.awt.event.MouseEvent;
import java.util.HashMap;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.border.Border;
opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -3365,7 +3365,7 @@
   * key manager provider enabled attribute.  This does not take any arguments.
   */
  public static final int MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED =
       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 313;
       CATEGORY_MASK_CONFIG | SEVERITY_MASK_INFORMATIONAL | 313;
opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -4347,6 +4347,7 @@
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to configure the connection security provider for a new
@@ -4378,7 +4379,13 @@
  public static final int MSGID_LDAP_CONNHANDLER_NO_TRUSTMANAGER_DN =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 403;
  /**
   * The message ID for the message that will be used as the description of the
   * configuration attribute specifying whether to enable the LDAPS
   * connection handler.
   */
  public static final int MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_INFORMATIONAL | 404;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -5306,6 +5313,9 @@
                    "configuration attribute will not take effect until the " +
                    "connection handler is disabled and re-enabled, or until " +
                    "the Directory Server is restarted.");
    registerMessage(MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE,
                    "Specifies whether to enable the LDAPS connection " +
                    "handler.");
    registerMessage(MSGID_LDAP_CONNHANDLER_DESCRIPTION_BACKLOG,
                    "Specifies the accept queue size, which controls the " +
                    "number of new connection attempts that may be allowed " +
opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -6796,6 +6796,139 @@
  /**
   * The message ID for the message that will be used as the description of the
   * ldapsPort argument.  This does not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 858;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to update the LDAP secure port.  This takes a single argument,
   * which is a message explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 859;
  /**
   * The message ID for the message that will be used as the description of the
   * enableStartTLS argument.  This does not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 860;
  /**
   * The message ID for the message that will be used as the description of the
   * Key Manager Provider DN argument for the connection handlers.  This does
   * not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 861;
  /**
   * The message ID for the message that will be used as the description of the
   * Trust Manager Provider DN argument for the connection handlers.  This does
   * not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 862;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to parse the DN provided for the key manager provider.  This
   * takes two arguments, the dn valud provided by the user and a message
   * explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 863;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to parse the DN provided for the trust manager provider.  This
   * takes two arguments, the dn valud provided by the user and a message
   * explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 864;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to enable StartTLS.  This takes a single argument,
   * which is a message explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 865;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to enable the key manager provider.  This takes a single
   * argument, which is a message explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 866;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to enable the trust manager provider.  This takes a single
   * argument, which is a message explaining the problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 867;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to update the key manager provider DN in one of the connection
   * handlers.  This takes a single argument, which is a message explaining the
   * problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 868;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to update the trust manager provider DN in one of the connection
   * handlers.  This takes a single argument, which is a message explaining the
   * problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 869;
  /**
   * The message ID for the message that will be used as the description of the
   * Certificate Key Manager Path for the Key Manager Provider entry.  This does
   * not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 870;
  /**
   * The message ID for the message that will be used as the description of the
   * Certificate Nick Name for the connection handlers.  This does
   * not take any arguments.
   */
  public static final int MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 871;
  /**
   * The message ID for the message that will be used if the user provided a key
   * manager provider path without providing a key manager provider DN.  This
   * takes as argument the two argument names.
   */
  public static final int MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 872;
  /**
   * The message ID for the message that will be used if an error occurs while
   * attempting to update the certificate nickname in one of the connection
   * handlers.  This takes a single argument, which is a message explaining the
   * problem that occurred.
   */
  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 873;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -7970,9 +8103,58 @@
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_LDAP_PORT,
                    "Specifies the port on which the Directory Server should " +
                    "listen for LDAP communication.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT,
                    "Specifies the port on which the Directory Server should " +
                    "listen for LDAPS communication.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_JMX_PORT,
                    "Specifies the port on which the Directory Server should " +
                    "listen for JMX communication.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS,
                    "Specifies whether to enable or not StartTLS.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN,
                    "Specifies the DN of the key manager provider to use " +
                    "for SSL and/or StartTLS.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN,
                    "Specifies the DN of the trust manager provider to use " +
                    "for SSL and/or StartTLS.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH,
                    "Specifies the path of the keystore to be used by the " +
                    "key manager provider.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME,
                    "Specifies the nickname of the certificate that the " +
                    "connection handler should use when accepting SSL-based " +
                    "connections or performing StartTLS negotiation.");
    registerMessage(MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN,
                    "An error occurred while attempting to parse key manager " +
                    "provider DN value \"%s\" as a DN:  %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN,
                    "An error occurred while attempting to parse trust " +
                    "manager provider DN value \"%s\" as a DN:  %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS,
                    "An error occurred while attempting to enable StartTLS: " +
                    "%s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER,
                    "An error occurred while attempting to enable key " +
                    "manager provider entry: %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER,
                    "An error occurred while attempting to enable trust " +
                    "manager provider entry: %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE,
                    "An error occurred while attempting to update the key " +
                    "manager provider DN used for LDAPS communication: " +
                    "%s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE,
                    "An error occurred while attempting to update the trust " +
                    "manager provider DN used for LDAPS communication: " +
                    "%s.");
    registerMessage(MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED,
                    "ERROR:  You must provide the %s argument when providing " +
                    "the %s argument.");
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME,
                    "An error occurred while attempting to update the " +
                    "nickname of the certificate that the " +
                    "connection handler should use when accepting SSL-based " +
                    "connections or performing StartTLS negotiation: %s.");
    registerMessage(MSGID_CONFIGDS_DESCRIPTION_BASE_DN,
                    "Specifies the base DN for user information in the " +
                    "Directory Server.  Multiple base DNs may be provided " +
@@ -8018,6 +8200,9 @@
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_LDAP_PORT,
                    "An error occurred while attempting to update the port " +
                    "on which to listen for LDAP communication:  %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT,
                    "An error occurred while attempting to update the port " +
                    "on which to listen for LDAPS communication:  %s.");
    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_JMX_PORT,
                    "An error occurred while attempting to update the port " +
                    "on which to listen for JMX communication:  %s.");
opends/src/server/org/opends/server/tools/ConfigureDS.java
@@ -31,6 +31,7 @@
import java.util.LinkedList;
import org.opends.server.api.ConfigHandler;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.DNConfigAttribute;
import org.opends.server.config.IntegerConfigAttribute;
@@ -52,6 +53,7 @@
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.messages.ConfigMessages.*;
import static org.opends.server.messages.ExtensionsMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ProtocolMessages.*;
import static org.opends.server.messages.ToolMessages.*;
@@ -102,6 +104,12 @@
  /**
   * The DN of the configuration entry defining the LDAPS connection handler.
   */
  private static final String DN_LDAPS_CONNECTION_HANDLER =
       "cn=LDAPS Connection Handler," + DN_CONNHANDLER_BASE;
  /**
   * The DN of the configuration entry defining the JMX connection handler.
   */
  private static final String DN_JMX_CONNECTION_HANDLER =
@@ -146,15 +154,20 @@
  public static int configMain(String[] args)
  {
    BooleanArgument   showUsage;
    BooleanArgument   enableStartTLS;
    FileBasedArgument rootPasswordFile;
    IntegerArgument   ldapPort;
    IntegerArgument   ldapsPort;
    IntegerArgument   jmxPort;
    StringArgument    baseDNString;
    StringArgument    configClass;
    StringArgument    configFile;
    StringArgument    rootDNString;
    StringArgument    rootPassword;
    StringArgument    keyManagerProviderDN;
    StringArgument    trustManagerProviderDN;
    StringArgument    certNickName;
    StringArgument    keyManagerPath;
    String toolDescription = getMessage(MSGID_CONFIGDS_TOOL_DESCRIPTION);
    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
@@ -182,12 +195,62 @@
                                     MSGID_CONFIGDS_DESCRIPTION_LDAP_PORT);
      argParser.addArgument(ldapPort);
      ldapsPort = new IntegerArgument("ldapsPort", 'P', "ldapsPort", false,
          false, true, "{ldapPort}", 636, null, true, 1, true, 65535,
          MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT);
      argParser.addArgument(ldapsPort);
      enableStartTLS = new BooleanArgument("enableStartTLS",
          OPTION_SHORT_START_TLS, "enableStartTLS",
          MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS);
      argParser.addArgument(enableStartTLS);
      jmxPort = new IntegerArgument("jmxport", 'x', "jmxPort", false, false,
          true, "{jmxPort}", SetupUtils.getDefaultJMXPort(), null, true, 1,
          true, 65535,
          MSGID_CONFIGDS_DESCRIPTION_JMX_PORT);
      argParser.addArgument(jmxPort);
      keyManagerProviderDN = new StringArgument("keymanagerproviderdn",
          'k',
          "keyManagerProviderDN",
          false, false,
          true, "{keyManagerProviderDN}",
          null,
          null,
          MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN);
      argParser.addArgument(keyManagerProviderDN);
      trustManagerProviderDN = new StringArgument("trustmanagerproviderdn",
          't',
          "trustManagerProviderDN",
          false, false,
          true, "{trustManagerProviderDN}",
          null,
          null,
          MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN);
      argParser.addArgument(trustManagerProviderDN);
      keyManagerPath = new StringArgument("keymanagerpath",
          'm',
          "keyManagerPath",
          false, false, true,
          "{keyManagerPath}",
          null,
          null,
          MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH);
      argParser.addArgument(keyManagerPath);
      certNickName = new StringArgument("certnickname",
          'a',
          "certNickName",
          false, false,
          true, "{certNickName}",
          null,
          null,
          MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME);
      argParser.addArgument(certNickName);
      baseDNString = new StringArgument("basedn", OPTION_SHORT_BASEDN,
                                        OPTION_LONG_BASEDN, false, true,
                                        true, OPTION_VALUE_BASEDN,
@@ -399,6 +462,86 @@
      ConfigHandler configHandler = directoryServer.getConfigHandler();
      // Check that the key manager provided is valid.
      if (keyManagerProviderDN.isPresent())
      {
        DN dn = null;
        try
        {
          dn = DN.decode(keyManagerProviderDN.getValue());
        }
        catch (DirectoryException de)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN;
          String message = getMessage(msgID,
              keyManagerProviderDN.getValue(),
              de.getErrorMessage());
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
        try
        {
          configHandler.getConfigEntry(dn);
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIG_KEYMANAGER_CANNOT_GET_BASE;
          String message = getMessage(msgID,
              keyManagerProviderDN.getValue(),
              String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // Check that the trust manager provided is valid.
      if (trustManagerProviderDN.isPresent())
      {
        DN dn = null;
        try
        {
          dn = DN.decode(trustManagerProviderDN.getValue());
        }
        catch (DirectoryException de)
        {
          int  msgID   = MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN;
          String message = getMessage(msgID,
              trustManagerProviderDN.getValue(),
              de.getErrorMessage());
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
        try
        {
          configHandler.getConfigEntry(dn);
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIG_TRUSTMANAGER_CANNOT_GET_BASE;
          String message = getMessage(msgID,
              trustManagerProviderDN.getValue(),
              String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // Check that the keystore path values are valid.
      if (keyManagerPath.isPresent())
      {
        if (!keyManagerProviderDN.isPresent())
        {
          int    msgID   = MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED;
          String message = getMessage(msgID,
              keyManagerProviderDN.getLongIdentifier(),
              keyManagerPath.getLongIdentifier());
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // If one or more base DNs were specified, then update the config
      // accordingly.
      if (baseDNs != null)
@@ -449,6 +592,36 @@
        }
      }
//    If an LDAPS port was specified, then update the config accordingly.
      if (ldapsPort.isPresent())
      {
        try
        {
          DN ldapListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
          ConfigEntry configEntry =
               configHandler.getConfigEntry(ldapListenerDN);
          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT;
          IntegerConfigAttribute portAttr =
               new IntegerConfigAttribute(ATTR_LISTEN_PORT, getMessage(msgID),
                                          true, false, true, true, 1, true,
                                          65535, ldapsPort.getIntValue());
          configEntry.putConfigAttribute(portAttr);
          msgID = MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE;
          BooleanConfigAttribute enablePortAttr =
            new BooleanConfigAttribute(ATTR_CONNECTION_HANDLER_ENABLED,
                getMessage(msgID), true, true, true);
          configEntry.putConfigAttribute(enablePortAttr);
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT;
          String message = getMessage(msgID, String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
//    If an JMX port was specified, then update the config accordingly.
      if (jmxPort.isPresent())
      {
@@ -474,6 +647,235 @@
        }
      }
      // Start TLS configuration
      if (enableStartTLS.isPresent())
      {
        try
        {
          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
          ConfigEntry configEntry =
               configHandler.getConfigEntry(ldapListenerDN);
          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS;
          BooleanConfigAttribute startTLS =
            new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS,
                getMessage(msgID), true, true, true);
          configEntry.putConfigAttribute(startTLS);
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS;
          String message = getMessage(msgID, String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // Key manager provider
      if (keyManagerProviderDN.isPresent())
      {
        if (enableStartTLS.isPresent() || ldapsPort.isPresent())
        {
          try
          {
            // Enable the key manager
            DN dn = DN.decode(keyManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
            int msgID = MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED;
            BooleanConfigAttribute enableAttr =
              new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
                  getMessage(msgID), true, true, true);
            configEntry.putConfigAttribute(enableAttr);
          }
          catch (Exception e)
          {
            int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER;
            String message = getMessage(msgID, String.valueOf(e));
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
        try
        {
          if (enableStartTLS.isPresent())
          {
            // Use the key manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapListenerDN);
            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN;
            StringConfigAttribute keyManagerProviderAttr =
              new StringConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID),
                  false, false, true, keyManagerProviderDN.getValue());
            configEntry.putConfigAttribute(keyManagerProviderAttr);
          }
          if (ldapsPort.isPresent())
          {
            // Use the key manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapsListenerDN);
            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN;
            StringConfigAttribute keyManagerProviderAttr =
              new StringConfigAttribute(ATTR_KEYMANAGER_DN,
                  getMessage(msgID), false, false,
                  true, keyManagerProviderDN.getValue());
            configEntry.putConfigAttribute(keyManagerProviderAttr);
          }
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE;
          String message = getMessage(msgID, String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
        if (keyManagerPath.isPresent())
        {
          try
          {
            // Enable the key manager
            DN dn = DN.decode(keyManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
            int msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_FILE;
            StringConfigAttribute pathAttr =
              new StringConfigAttribute(ATTR_KEYSTORE_FILE,
                  getMessage(msgID), true, true, true,
                  keyManagerPath.getValue());
            configEntry.putConfigAttribute(pathAttr);
          }
          catch (Exception e)
          {
            String message = String.valueOf(e);
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
      }
      if (trustManagerProviderDN.isPresent())
      {
        if (enableStartTLS.isPresent() || ldapsPort.isPresent())
        {
          // Enable the trust manager
          try
          {
            DN dn = DN.decode(trustManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
            int msgID = MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED;
            BooleanConfigAttribute enableAttr =
              new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
                  getMessage(msgID), true, true, true);
            configEntry.putConfigAttribute(enableAttr);
          }
          catch (Exception e)
          {
            int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER;
            String message = getMessage(msgID, String.valueOf(e));
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
        try
        {
          if (enableStartTLS.isPresent())
          {
            // Use the trust manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapListenerDN);
            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN;
            StringConfigAttribute trustManagerProviderAttr =
              new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
                  getMessage(msgID), false, false,
                  true, trustManagerProviderDN.getValue());
            configEntry.putConfigAttribute(trustManagerProviderAttr);
          }
          if (ldapsPort.isPresent())
          {
            // Use the trust manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapsListenerDN);
            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN;
            StringConfigAttribute trustManagerProviderAttr =
              new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
                  getMessage(msgID), false, false,
                  true, trustManagerProviderDN.getValue());
            configEntry.putConfigAttribute(trustManagerProviderAttr);
          }
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE;
          String message = getMessage(msgID, String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      if (certNickName.isPresent())
      {
        try
        {
          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME;
          StringConfigAttribute certNickNameAttr =
            new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME, getMessage(msgID),
                false, false, true, certNickName.getValue());
          if (ldapPort.isPresent())
          {
            // Use the key manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapListenerDN);
            configEntry.putConfigAttribute(certNickNameAttr);
          }
          if (ldapsPort.isPresent())
          {
            // Use the key manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapsListenerDN);
            configEntry.putConfigAttribute(certNickNameAttr);
          }
          if (jmxPort.isPresent())
          {
            msgID = MSGID_JMX_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME;
            certNickNameAttr = new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME,
                getMessage(msgID), false, false, true, certNickName.getValue());
            // Use the key manager specified for the JMX connection handler.
            DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(jmxListenerDN);
            configEntry.putConfigAttribute(certNickNameAttr);
          }
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME;
          String message = getMessage(msgID, String.valueOf(e));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // If a root user DN and password were specified, then update the config
      // accordingly.
opends/src/server/org/opends/server/util/CertificateManager.java
@@ -332,6 +332,7 @@
      aliasList.add(aliasEnumeration.nextElement());
    }
    String[] aliases = new String[aliasList.size()];
    return aliasList.toArray(aliases);
  }
@@ -646,7 +647,6 @@
  }
  /**
   * Removes the specified certificate from the key store.
   *
@@ -855,6 +855,19 @@
    {
      throw new KeyStoreException(String.valueOf(e), e);
    }
    finally
    {
      if (keyStoreInputStream != null)
      {
        try
        {
          keyStoreInputStream.close();
        }
        catch (Throwable t)
        {
        }
      }
    }
  }
}