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

jvergara
30.53.2007 d65316c746990cbe4c2b433b007afe00e9492c36
The following modifications are done in order to be able to handle properly secure connections in both the status command-line and the status panel.  Some options to specify a keystore, a trustore, etc. have been added to the status command-line so that is consistent with the other command-lines that use LDAP.  As for these command-lines if the user does not specify to use Start TLS or LDAPS, the command-line will try to use LDAP to connect. But if there is no LDAP port enabled, the command-line will try to connect to the LDAPS port.

Concerning the status panel, it will try to use the most secure method to connect to the server, if the servers is configured to use SSL or Start TLS and the presented certificate is not trusted by default by the JDK, we will present to the user in order to be accepted.
2 files added
1 files renamed
16 files modified
1354 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java 24 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Configuration.java 62 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Constants.java 2 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 31 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java 15 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java 8 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java 13 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java 2 ●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConfigException.java 47 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java 92 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java 202 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java 53 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java 69 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/StatusCli.java 399 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java 38 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties 23 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java 270 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
@@ -29,6 +29,7 @@
import java.io.IOException;
import java.net.ConnectException;
import java.security.GeneralSecurityException;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
@@ -45,6 +46,7 @@
import javax.naming.ldap.StartTlsResponse;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
/**
@@ -495,6 +497,28 @@
  }
  /**
   * Tells whether the provided Throwable was caused because of a problem with
   * a certificate while trying to establish a connection.
   * @param t the Throwable to analyze.
   * @return <CODE>true</CODE> if the provided Throwable was caused because of a
   * problem with a certificate while trying to establish a connection and
   * <CODE>false</CODE> otherwise.
   */
  public static boolean isCertificateException(Throwable t)
  {
    boolean returnValue = false;
    while (!returnValue && (t != null))
    {
      returnValue = (t instanceof SSLHandshakeException) ||
      (t instanceof GeneralSecurityException);
      t = t.getCause();
    }
    return returnValue;
  }
  /**
   * Returns the String representation of the first value of an attribute in a
   * LDAP entry.
   * @param entry the entry.
opends/src/quicksetup/org/opends/quicksetup/Configuration.java
@@ -91,7 +91,7 @@
   * the configuration file.
   */
  public int getPort() throws IOException {
    return getPort("ds-cfg-listen-port");
    return getLDAPPort("ds-cfg-listen-port");
  }
  /**
@@ -103,7 +103,54 @@
   */
  public int getSecurePort() throws IOException {
    // TODO find out which is the attribute for this port.
    return getPort("ds-cfg-listen-secure-port");
    return getLDAPPort("ds-cfg-listen-secure-port");
  }
  /**
   * Tells whether this server is configured as a replication server or not.
   * @return <CODE>true</CODE> if the server is configured as a Replication
   * Server and <CODE>false</CODE> otherwise.
   * @throws IOException if there were problems reading the information from
   * the configuration file.
   */
  public boolean isReplicationServer() throws IOException
  {
    return getReplicationPort() != -1;
  }
  /**
   * Provides the Replication port as is specified in the config.ldif file.
   * Returns -1 if this server is not a Replication Server.
   *
   * @return the Replication port specified in the config.ldif file.
   * @throws IOException if there were problems reading the information from
   * the configuration file.
   */
  public int getReplicationPort() throws IOException {
    int port = -1;
    String contents = getContents();
    int index = contents.indexOf("cn=replication server");
    if (index != -1) {
      String attrWithPoints = "ds-cfg-replication-server-port:";
      int index1 = contents.indexOf(attrWithPoints, index);
      if (index1 != -1) {
        int index2 =
                contents.indexOf(Constants.LINE_SEPARATOR, index1);
        if (index2 != -1) {
          String sPort =
                  contents.substring(attrWithPoints.length() +
                          index1,
                          index2).trim();
          try {
            port = Integer.parseInt(sPort);
          } catch (NumberFormatException nfe) {
            // do nothing;
          }
        }
      }
    }
    return port;
  }
  /**
@@ -119,7 +166,7 @@
    return getConfigurationValues("ds-cfg-log-file");
  }
  private int getPort(String portAttr) throws IOException {
  private int getLDAPPort(String portAttr) throws IOException {
    int port = -1;
    String contents = getContents();
    int index = contents.indexOf("cn=ldap connection handler");
@@ -239,6 +286,15 @@
    return getConfigurationValues("ds-cfg-backend-directory");
  }
  /**
   * Returns the list of base dns as they appear in the configuration file.
   *
   * @return the list of base dns as they appear in the configuration file.
   * @throws IOException if there is a problem reading the config file.
   */
  public Set<String> getBaseDNs() throws IOException {
    return getConfigurationValues("ds-cfg-backend-base-dn");
  }
  /**
   * Loads the contents of the configuration file into memory.
opends/src/quicksetup/org/opends/quicksetup/Constants.java
@@ -72,6 +72,8 @@
  /** Default dynamic name of directory manager. */
  public static final String DIRECTORY_MANAGER_DN = "cn=Directory Manager";
  /** Default global admin UID. */
  public static final String GLOBAL_ADMIN_UID = "admin";
  /** These HTML tags cause a line break in formatted text. */
  public static final String[] BREAKING_TAGS = {
          HTML_LINE_BREAK,
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -115,7 +115,7 @@
        DataReplicationOptions.Type.STANDALONE, data,
        getDefaultReplicationPort());
    setReplicationOptions(repl);
    setGlobalAdministratorUID("admin");
    setGlobalAdministratorUID(Constants.GLOBAL_ADMIN_UID);
    SuffixesToReplicateOptions suffixes =
      new SuffixesToReplicateOptions(
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -144,6 +144,7 @@
finish-button-tooltip=Finish Setup
close-button-label=Close
close-button-tooltip=Close Setup Window
close-progress-button-tooltip=Close Progress Dialog
close-button-install-tooltip=Close Setup Window
close-button-uninstall-tooltip=Close Uninstall Window
quit-button-label=Quit
@@ -189,6 +190,17 @@
uninstallation can continue. Do you want the uninstaller to stop \
the server for you and continue with the uninstall? If you click \
No, you will need to stop the server manually to continue.
confirm-uninstall-replication-server-running-title=Confirmation Required
confirm-uninstall-replication-server-running-msg=This server is configured to \
perform replication.\nIn order to remove references to this server in other \
servers you must provide administrator authentication.\n\nClick on 'Yes' to \
provide authentication to remove the remote references.
confirm-uninstall-replication-server-not-running-title=Confirmation Required
confirm-uninstall-replication-server-not-running-msg=This server is configured \
to perform replication.\nIn order to remove references to this server in other \
servers the server will be started and then you must provide administrator \
authentication.\n\nClick on 'Yes' to start the server and then provide \
authentication to remove the remote references.
confirm-uninstall-server-running-title=Server is Running
confirm-cancel-title=Confirmation Required
confirm-cancel-prompt=Cancel the running operation?
@@ -343,7 +355,7 @@
cannot-connect-to-shutdown-without-cause=Could not connect to the Directory \
Server with the provided credentials.\nCheck that the Administrative User DN \
and password are valid.
server-not-running-msg=The Directory Server is not running.  Click OK to \
server-not-running-msg=The Directory Server is not running.  Click 'Yes' to \
continue the uninstall.
server-not-running-title=Directory Server not Running
@@ -983,6 +995,7 @@
##
# Progress messages
#
progress-title=Progress
progress-downloading=Downloading
progress-done=Done.
progress-points=.....
@@ -1351,6 +1364,22 @@
installandupgrader-rbupgrade-tooltip=Select to upgrade an existing server \
instance.
#
# Progress Dialog
#
progress-dialog-title=Progress
summary-starting=Starting Server...
summary-stopping=Stopping Server...
summary-start-error=An error occurred Starting Server.  Check 'Details' text \
area for more information.
summary-stop-error=An error occurred Stopping Server.  Check 'Details' text \
area for more information.
error-starting-server-code=Error Starting Directory Server.  Error code: {0}.
summary-start-success=OpenDS Started Successfully.
summary-stop-success=OpenDS Stopped Successfully.
general-action-required=Action Required
general-warning=Warning
general-info=Information
opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
@@ -101,7 +101,7 @@
    pack();
    if (getPreferredSize().width > parent.getWidth())
    {
      setPreferredSize(new Dimension(parent.getWidth() - 20,
      setPreferredSize(new Dimension(Math.max(parent.getWidth() - 20, 400),
          getPreferredSize().height));
    }
    pack();
@@ -204,9 +204,18 @@
    topPanel.add(Box.createHorizontalStrut(
        certificateDetails.getPreferredSize().width), gbc);
    gbc.insets.top = 0;
    gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL;
    gbc.weighty = 1.0;
    topPanel.add(certificateDetails, gbc);
    JPanel auxPanel = new JPanel(new GridBagLayout());
    gbc.weightx = 0.0;
    gbc.insets = UIFactory.getEmptyInsets();
    gbc.gridwidth = GridBagConstraints.RELATIVE;
    auxPanel.add(Box.createVerticalStrut(100), gbc);
    gbc.weightx = 1.0;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    auxPanel.add(certificateDetails, gbc);
    gbc.insets = UIFactory.getCurrentStepPanelInsets();
    gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL;
    topPanel.add(auxPanel, gbc);
    certificateDetails.setVisible(false);
    gbc.weighty = 0.2;
    gbc.insets = UIFactory.getEmptyInsets();
opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java
File was renamed from opends/src/statuspanel/org/opends/statuspanel/ui/ProgressDialog.java
@@ -25,7 +25,7 @@
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.statuspanel.ui;
package org.opends.quicksetup.ui;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
@@ -46,12 +46,10 @@
import javax.swing.event.HyperlinkListener;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.util.HtmlProgressMessageFormatter;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.statuspanel.i18n.ResourceProvider;
/**
 * This panel is used to show the progress of the start/stop/restart operations.
 *
@@ -87,7 +85,7 @@
  {
    super(frame);
    this.parent = frame;
    setTitle(getMsg("statuspanel-dialog-title"));
    setTitle(getMsg("progress-dialog-title"));
    createLayout();
  }
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
@@ -184,7 +184,7 @@
  /**
   * ProgressUpdateListener implementation. Here we take the
   * ProgressUpdateEvent and create an ProgressDescriptor that
   * ProgressUpdateEvent and create a ProgressDescriptor that
   * will be used to update the progress dialog.
   *
   * @param ev the ProgressUpdateEvent we receive.
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -34,7 +34,6 @@
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -44,7 +43,6 @@
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
@@ -894,16 +892,7 @@
 */
  public static boolean isCertificateException(Throwable t)
  {
    boolean returnValue = false;
    while (!returnValue && (t != null))
    {
      returnValue = (t instanceof SSLHandshakeException) ||
      (t instanceof GeneralSecurityException);
      t = t.getCause();
    }
    return returnValue;
    return ConnectionUtils.isCertificateException(t);
  }
  /**
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
@@ -168,7 +168,7 @@
  private FileBasedArgument keyStorePasswordFileArg = null;
  /**
   * The 'keyStorePasswordFile' global argument.
   * The 'certNicknameArg' global argument.
   */
  private StringArgument certNicknameArg = null;
opends/src/statuspanel/org/opends/statuspanel/ConfigException.java
New file
@@ -0,0 +1,47 @@
/*
 * 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.statuspanel;
/**
 * Exception thrown when there is an error with the configuration (for instance
 * a valid URL for the requested protocol could not be found).
 */
public class ConfigException extends Exception
{
  private static final long serialVersionUID = 1266482779183126905L;
  /**
   * Constructor for the exception.
   * @param msg the localized message to be used.
   */
  public ConfigException(String msg)
  {
    super(msg);
  }
}
opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
@@ -33,6 +33,8 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.opends.server.core.DirectoryServer;
import org.opends.server.util.LDIFException;
@@ -43,9 +45,9 @@
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ObjectClass;
import org.opends.statuspanel.i18n.ResourceProvider;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.Installation;
import org.opends.statuspanel.i18n.ResourceProvider;
/**
 * This class is used to retrieve configuration information directly from the
@@ -72,6 +74,8 @@
  private HashSet<ListenerDescriptor> listeners =
    new HashSet<ListenerDescriptor>();
  private HashSet<ListenerDescriptor> startTLSListeners =
    new HashSet<ListenerDescriptor>();
  private HashSet<DatabaseDescriptor> databases =
    new HashSet<DatabaseDescriptor>();
  private HashSet<String> administrativeUsers = new HashSet<String>();
@@ -79,6 +83,9 @@
  private boolean replicationConfigured = false;
  private HashSet<String> replicatedSuffixes = new HashSet<String>();
  private static final Logger LOG =
    Logger.getLogger(ConfigFromFile.class.getName());
  /**
   * Default constructor.
   *
@@ -96,6 +103,7 @@
  {
    errorMessage = null;
    listeners.clear();
    startTLSListeners.clear();
    databases.clear();
    administrativeUsers.clear();
    replicationConfigured = false;
@@ -117,16 +125,19 @@
    }
    catch (IOException ioe)
    {
      LOG.log(Level.SEVERE, "Error reading config file: "+ioe, ioe);
      errorMessage = Utils.getThrowableMsg(getI18n(),
          "error-reading-config-file", null, ioe);
    }
    catch (LDIFException le)
    {
      LOG.log(Level.SEVERE, "Error reading config file: "+le, le);
      errorMessage = Utils.getThrowableMsg(getI18n(),
          "error-reading-config-file", null, le);
    }
    catch (Throwable t)
    {
      LOG.log(Level.SEVERE, "Error reading config file: "+t, t);
      // Bug
      t.printStackTrace();
      errorMessage = Utils.getThrowableMsg(getI18n(),
@@ -199,6 +210,64 @@
   */
  public String getLDAPURL()
  {
    return getLDAPURL(false);
  }
  /**
   * Returns the ldaps URL that we can use to connect to the server based in
   * what we found in the config.ldif file.
   * @return the ldaps URL that we can use to connect to the server based in
   * what we found in the config.ldif file.
   */
  public String getLDAPSURL()
  {
    return getLDAPURL(true);
  }
  /**
   * Returns the ldap URL that we can use to connect to the server using Start
   * TLS based in what we found in the config.ldif file.
   * @return the ldap URL that we can use to connect to the server using Start
   * TLS based in what we found in the config.ldif file.
   */
  public String getStartTLSURL()
  {
    String url = null;
    for (ListenerDescriptor desc : startTLSListeners)
    {
      if (desc.getState() == ListenerDescriptor.State.ENABLED)
      {
        int port = -1;
        try
        {
          String addressPort = desc.getAddressPort();
          int index = addressPort.indexOf(":");
          if (index != -1)
          {
            port = Integer.parseInt(addressPort.substring(index+1));
          }
          else
          {
            port = Integer.parseInt(addressPort);
          }
        }
        catch (Exception ex)
        {
          // Could not get the port
        }
        if (port != -1)
        {
          url = "ldap://localhost:"+port;
          break;
        }
      }
    }
    return url;
  }
  private String getLDAPURL(boolean secure)
  {
    String url = null;
    for (ListenerDescriptor desc : getListeners())
@@ -227,16 +296,17 @@
        if (port != -1)
        {
          if (desc.getProtocol() == ListenerDescriptor.Protocol.LDAP)
          if (!secure &&
              (desc.getProtocol() == ListenerDescriptor.Protocol.LDAP))
          {
            url = "ldap://localhost:"+port;
            /* We prefer to test using the LDAP port: do not continue
             * searching */
            break;
          }
          else if (desc.getProtocol() == ListenerDescriptor.Protocol.LDAPS)
          if (secure &&
              (desc.getProtocol() == ListenerDescriptor.Protocol.LDAPS))
          {
            url = "ldaps://localhost:"+port;
            break;
          }
        }
      }
@@ -383,6 +453,18 @@
    }
    listeners.add(new ListenerDescriptor(addressPort, protocol,
        protocolDescription, state));
    if (protocol == ListenerDescriptor.Protocol.LDAP)
    {
      String allowStartTLS = getFirstValue(entry, "ds-cfg-allow-start-tls");
      if (allowStartTLS != null)
      {
        if ("true".equalsIgnoreCase(allowStartTLS.trim()))
        {
          startTLSListeners.add(new ListenerDescriptor(addressPort, protocol,
              protocolDescription, state));
        }
      }
    }
  }
  /**
opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
@@ -43,6 +43,7 @@
import javax.naming.ldap.LdapName;
import org.opends.statuspanel.i18n.ResourceProvider;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.util.Utils;
/**
@@ -67,7 +68,10 @@
  private String dn;
  private String pwd;
  private String ldapUrl;
  private String lastUrl;
  private ConnectionProtocolPolicy policy;
  private ConfigFromFile offlineConf;
  private ApplicationTrustManager trustManager;
  private InitialLdapContext ctx;
  private String javaVersion;
@@ -83,15 +87,28 @@
  /**
   * Sets the connection information required to contact the server using LDAP.
   * @param ldapUrl the LDAP URL of the server.
   * @param offlineConf the ConfigFromFile object used to retrieve the LDAP URL
   * that will be used to connect to the server.
   * @param policy the configuration policy to be used (whether we prefer the
   * most secure, the less secure, a specific method...).
   * @param dn the authentication Distinguished Name to bind.
   * @param pwd the authentication password to bind.
   * @param trustManager the trust manager to be used for the secure
   * connections.
   * @throws ConfigException if a valid URL could not be found with the provided
   * parameters.
   */
  public void setConnectionInfo(String ldapUrl, String dn, String pwd)
  public void setConnectionInfo(ConfigFromFile offlineConf,
      ConnectionProtocolPolicy policy, String dn, String pwd,
      ApplicationTrustManager trustManager) throws ConfigException
  {
    if (ldapUrl == null)
    if (offlineConf == null)
    {
      throw new IllegalArgumentException("ldapUrl cannot be null.");
      throw new IllegalArgumentException("offlineConf cannot be null.");
    }
    if (policy == null)
    {
      throw new IllegalArgumentException("policy cannot be null.");
    }
    if (dn == null)
    {
@@ -101,9 +118,15 @@
    {
      throw new IllegalArgumentException("pwd cannot be null.");
    }
    this.trustManager = trustManager;
    this.offlineConf = offlineConf;
    this.policy = policy;
    String ldapUrl = getURL(offlineConf, policy);
    if (!Utils.areDnsEqual(dn, this.dn) ||
        !pwd.equals(this.pwd) ||
        !ldapUrl.equals(this.ldapUrl))
        (policy != this.policy) ||
        !ldapUrl.equals(lastUrl))
    {
      if (ctx != null)
      {
@@ -118,7 +141,7 @@
      }
    }
    this.ldapUrl = ldapUrl;
    this.lastUrl = ldapUrl;
    this.dn = dn;
    this.pwd = pwd;
  }
@@ -265,8 +288,11 @@
   * @return the InitialLdapContext object to be used to retrieve configuration
   * and monitoring information.
   * @throws NamingException if we could not get an InitialLdapContext.
   * @throws ConfigException if we could not retrieve a valid LDAP URL in
   * the configuration.
   */
  private InitialLdapContext getDirContext() throws NamingException
  private InitialLdapContext getDirContext() throws NamingException,
  ConfigException
  {
    if (ctx != null)
    {
@@ -288,8 +314,86 @@
    }
    if (ctx == null)
    {
      ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
          Utils.getDefaultLDAPTimeout(), null);
      String ldapUrl = offlineConf.getLDAPURL();
      String startTlsUrl = offlineConf.getStartTLSURL();
      String ldapsUrl = offlineConf.getLDAPSURL();
      switch (policy)
      {
      case USE_STARTTLS:
        if (startTlsUrl != null)
        {
          ctx = Utils.createStartTLSContext(startTlsUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null, trustManager, null);
        }
        else
        {
          throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
        }
        break;
      case USE_LDAPS:
        if (ldapsUrl != null)
        {
          ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null, trustManager);
        }
        else
        {
          throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
        }
        break;
      case USE_LDAP:
        if (ldapUrl != null)
        {
          ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null);
        }
        else
        {
          throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
        }
        break;
      case USE_MOST_SECURE_AVAILABLE:
        if (ldapsUrl != null)
        {
          ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null, trustManager);
        }
        else if (startTlsUrl != null)
        {
          ctx = Utils.createStartTLSContext(startTlsUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null,
              trustManager, null);
        }
        else if (ldapUrl != null)
        {
          ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null);
        }
        else
        {
          throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
        }
        break;
      case USE_LESS_SECURE_AVAILABLE:
        if (ldapUrl != null)
        {
          ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null);
        }
        else if (ldapsUrl != null)
        {
          ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd,
              Utils.getDefaultLDAPTimeout(), null, trustManager);
        }
        else
        {
          throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
        }
        break;
        default:
          throw new IllegalStateException("Unknown connection policy: "+
              policy);
      }
    }
    return ctx;
  }
@@ -908,4 +1012,82 @@
  {
    return ResourceProvider.getInstance();
  }
  private String getURL(ConfigFromFile offlineConf,
      ConnectionProtocolPolicy policy) throws ConfigException
  {
    String url;
    String ldapUrl = offlineConf.getLDAPURL();
    String startTlsUrl = offlineConf.getStartTLSURL();
    String ldapsUrl = offlineConf.getLDAPSURL();
    switch (policy)
    {
    case USE_STARTTLS:
      if (startTlsUrl != null)
      {
        url = startTlsUrl;
      }
      else
      {
        throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
      }
      break;
    case USE_LDAPS:
      if (ldapsUrl != null)
      {
        url = ldapsUrl;
      }
      else
      {
        throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
      }
      break;
    case USE_LDAP:
      if (ldapUrl != null)
      {
        url = ldapUrl;
      }
      else
      {
        throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
      }
      break;
    case USE_MOST_SECURE_AVAILABLE:
      if (ldapsUrl != null)
      {
        url = ldapsUrl;
      }
      else if (startTlsUrl != null)
      {
        url = startTlsUrl;
      }
      else if (ldapUrl != null)
      {
        url = ldapUrl;
      }
      else
      {
        throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
      }
      break;
    case USE_LESS_SECURE_AVAILABLE:
      if (ldapUrl != null)
      {
        url = ldapUrl;
      }
      else if (ldapsUrl != null)
      {
        url = ldapsUrl;
      }
      else
      {
        throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
      }
      break;
      default:
        throw new IllegalStateException("Unknown connection policy: "+
            policy);
    }
    return url;
  }
}
opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java
New file
@@ -0,0 +1,53 @@
/*
 * 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.statuspanel;
/** Policy to follow to choose the protocol to be used. */
public enum ConnectionProtocolPolicy
{
  /**
   * Force to use Start TLS.
   */
  USE_STARTTLS,
  /**
   * Force to use LDAP.
   */
  USE_LDAP,
  /**
   * Force to use LDAPs.
   */
  USE_LDAPS,
  /**
   * Use the most secure available (LDAPs, StartTLS and finally LDAP).
   */
  USE_MOST_SECURE_AVAILABLE,
  /**
   * Use the less secure available (LDAP, and then LDAPs).
   */
  USE_LESS_SECURE_AVAILABLE,
}
opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java
@@ -29,7 +29,10 @@
import java.io.File;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.util.Utils;
import org.opends.statuspanel.event.ServerStatusChangeEvent;
@@ -47,6 +50,7 @@
{
  private String dn;
  private String pwd;
  private ApplicationTrustManager trustManager;
  private ServerStatusDescriptor lastDescriptor;
  private boolean stopPooling;
  private Thread poolingThread;
@@ -56,23 +60,28 @@
  private boolean stopping;
  private ConfigFromFile offLineConf = new ConfigFromFile();
  private ConfigFromLDAP onLineConf = new ConfigFromLDAP();
  private String ldapUrl;
  private int nTriesWithErrorOnline;
  private ConnectionProtocolPolicy policy;
  /* The pooling periods */
  private static final int OFFLINE_POOLING_PERIOD = 6000;
  private static final int ONLINE_POOLING_PERIOD = 4000;
  private static final Logger LOG =
    Logger.getLogger(ServerStatusPooler.class.getName());
  /**
   * Default constructor.
   * @param policy the configuration policy to be used (whether we prefer the
   * most secure, the less secure, a specific method...).
   */
  public ServerStatusPooler()
  public ServerStatusPooler(ConnectionProtocolPolicy policy)
  {
    /* This is required to retrieve the ldap url to be used by the
     * ConfigFromLDAP class.
     */
    offLineConf.readConfiguration();
    ldapUrl = offLineConf.getLDAPURL();
    this.policy = policy;
  }
  /**
@@ -232,13 +241,18 @@
   * information using LDAP.
   * @param dn the authentication Distinguished Name to bind.
   * @param pwd the authentication password to bind.
   * @param trustManager the trust manager to be used for the secure
   * connections.
   * @throws ConfigException if a valid URL could not be found with the provided
   * parameters.
   */
  public void setAuthentication(String dn, String pwd)
  public void setAuthentication(String dn, String pwd,
      ApplicationTrustManager trustManager) throws ConfigException
  {
    this.dn = dn;
    this.pwd = pwd;
    if ((ldapUrl != null) && (poolingThread != null) &&
        poolingThread.isAlive() && !stopPooling)
    this.trustManager = trustManager;
    if ((poolingThread != null) && poolingThread.isAlive() && !stopPooling)
    {
      /* If we are pooling, stop the pooling update the connection information
       * and restart the pooling.  Set the stopPooling boolean to true to
@@ -258,12 +272,12 @@
        t.printStackTrace();
      }
      poolingThread = null;
      onLineConf.setConnectionInfo(ldapUrl, dn, pwd);
      onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager);
      startPooling();
    }
    else if (ldapUrl != null)
    else
    {
      onLineConf.setConnectionInfo(ldapUrl, dn, pwd);
      onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager);
    }
  }
@@ -330,20 +344,9 @@
          desc.setListeners(new HashSet<ListenerDescriptor>());
          desc.setOpenConnections(-1);
        }
        else if (ldapUrl != null)
        {
          updateDescriptorWithOnLineInfo(desc);
        }
        else
        {
          /* We cannot retrieve an ldapurl from the config file.  Display
           * what we got in the config file.
           */
          updateDescriptorWithOffLineInfo(desc);
          if (desc.getErrorMessage() != null)
          {
            desc.setErrorMessage(getMsg("could-not-find-valid-ldapurl"));
          }
          updateDescriptorWithOnLineInfo(desc);
        }
      }
      catch (Exception ex)
@@ -372,10 +375,17 @@
    desc.setDatabases(offLineConf.getDatabases());
    desc.setListeners(offLineConf.getListeners());
    desc.setErrorMessage(offLineConf.getErrorMessage());
    ldapUrl = offLineConf.getLDAPURL();
    if ((ldapUrl != null) && (dn != null) && (pwd != null))
    if ((dn != null) && (pwd != null))
    {
      onLineConf.setConnectionInfo(ldapUrl, dn, pwd);
      try
      {
        onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd,
            trustManager);
      }
      catch (ConfigException ce)
      {
        LOG.log(Level.WARNING, "Error retrieving LDAP URL: "+ce, ce);
      }
    }
    desc.setOpenConnections(-1);
    desc.setJavaVersion(null);
@@ -406,8 +416,15 @@
      if (nTriesWithErrorOnline >= 5)
      {
        offLineConf.readConfiguration();
        ldapUrl = offLineConf.getLDAPURL();
        onLineConf.setConnectionInfo(ldapUrl, dn, pwd);
        try
        {
          onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd,
              trustManager);
        }
        catch (ConfigException ce)
        {
          desc.setErrorMessage(ce.getMessage());
        }
        nTriesWithErrorOnline = 0;
      }
    }
opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
@@ -29,15 +29,26 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.KeyManager;
import javax.swing.table.TableModel;
import org.opends.admin.ads.util.ApplicationKeyManager;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.util.Utils;
@@ -48,11 +59,13 @@
import org.opends.statuspanel.ui.DatabasesTableModel;
import org.opends.statuspanel.ui.ListenersTableModel;
import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
import org.opends.server.messages.MessageHandler;
import org.opends.server.util.PasswordReader;
import org.opends.server.util.SelectableCertificateKeyManager;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentParser;
@@ -77,6 +90,66 @@
  private boolean displayMustStartLegend;
  /**
   * The 'binDN' global argument.
   */
  private StringArgument bindDnArg = null;
  /**
   * The 'bindPasswordFile' global argument.
   */
  private FileBasedArgument bindPasswordFileArg = null;
  /**
   * The 'bindPassword' global argument.
   */
  private StringArgument bindPasswordArg = null;
  /**
   * The 'trustAllArg' global argument.
   */
  private BooleanArgument trustAllArg = null;
  /**
   * The 'trustStore' global argument.
   */
  private StringArgument trustStorePathArg = null;
  /**
   * The 'trustStorePassword' global argument.
   */
  private StringArgument trustStorePasswordArg = null;
  /**
   * The 'trustStorePasswordFile' global argument.
   */
  private FileBasedArgument trustStorePasswordFileArg = null;
  /**
   * The 'keyStore' global argument.
   */
  private StringArgument keyStorePathArg = null;
  /**
   * The 'keyStorePassword' global argument.
   */
  private StringArgument keyStorePasswordArg = null;
  /**
   * The 'keyStorePasswordFile' global argument.
   */
  private FileBasedArgument keyStorePasswordFileArg = null;
  /**
   * The 'certNicknameArg' global argument.
   */
  private StringArgument certNicknameArg = null;
  /**
   * The Logger.
   */
  static private final Logger LOG = Logger.getLogger(StatusCli.class.getName());
  /**
   * Return code: Uninstall successful.
   */
  static int SUCCESSFUL = 0;
@@ -142,9 +215,12 @@
        new ArgumentParser(StatusPanelLauncher.class.getName(),
          getI18n().getMsg("status-cli-usage-description"), false);
    BooleanArgument showUsage;
    BooleanArgument useSSLArg;
    BooleanArgument startTLSArg;
    StringArgument bindDN;
    StringArgument bindPW;
    FileBasedArgument bindPWFile;
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_STATUSCLI_FILE_NAME;
@@ -154,9 +230,18 @@
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    try
    {
      useSSLArg = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL,
          OPTION_LONG_USE_SSL, MSGID_DESCRIPTION_USE_SSL);
      argParser.addArgument(useSSLArg);
      startTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS,
          OPTION_LONG_START_TLS,
          MSGID_DESCRIPTION_START_TLS);
      argParser.addArgument(startTLSArg);
      bindDN = new StringArgument("binddn", OPTION_SHORT_BINDDN,
          OPTION_LONG_BINDDN, false, false, true,
          OPTION_VALUE_BINDDN, null, null,
          OPTION_VALUE_BINDDN, "cn=Directory Manager", null,
          MSGID_STOPDS_DESCRIPTION_BINDDN);
      argParser.addArgument(bindDN);
@@ -175,6 +260,53 @@
          null, null,
          MSGID_STOPDS_DESCRIPTION_BINDPWFILE);
      argParser.addArgument(bindPWFile);
      trustAllArg = new BooleanArgument("trustAll", 'X', "trustAll",
          MSGID_DESCRIPTION_TRUSTALL);
      argParser.addArgument(trustAllArg);
      trustStorePathArg = new StringArgument("trustStorePath",
          OPTION_SHORT_TRUSTSTOREPATH, OPTION_LONG_TRUSTSTOREPATH, false,
          false, true, OPTION_VALUE_TRUSTSTOREPATH, null, null,
          MSGID_DESCRIPTION_TRUSTSTOREPATH);
      argParser.addArgument(trustStorePathArg);
      trustStorePasswordArg = new StringArgument("trustStorePassword", null,
          OPTION_LONG_TRUSTSTORE_PWD, false, false, true,
          OPTION_VALUE_TRUSTSTORE_PWD, null, null,
          MSGID_DESCRIPTION_TRUSTSTOREPASSWORD);
      argParser.addArgument(trustStorePasswordArg);
      trustStorePasswordFileArg =
        new FileBasedArgument("truststorepasswordfile",
          OPTION_SHORT_TRUSTSTORE_PWD_FILE, OPTION_LONG_TRUSTSTORE_PWD_FILE,
          false, false, OPTION_VALUE_TRUSTSTORE_PWD_FILE, null, null,
          MSGID_DESCRIPTION_TRUSTSTOREPASSWORD_FILE);
      argParser.addArgument(trustStorePasswordFileArg);
      keyStorePathArg = new StringArgument("keyStorePath",
          OPTION_SHORT_KEYSTOREPATH, OPTION_LONG_KEYSTOREPATH, false, false,
          true, OPTION_VALUE_KEYSTOREPATH, null, null,
          MSGID_DESCRIPTION_KEYSTOREPATH);
      argParser.addArgument(keyStorePathArg);
      keyStorePasswordArg = new StringArgument("keyStorePassword", null,
          OPTION_LONG_KEYSTORE_PWD, false, false, true,
          OPTION_VALUE_KEYSTORE_PWD, null, null,
          MSGID_DESCRIPTION_KEYSTOREPASSWORD);
      argParser.addArgument(keyStorePasswordArg);
      keyStorePasswordFileArg = new FileBasedArgument("keystorepasswordfile",
          OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false,
          false, OPTION_VALUE_KEYSTORE_PWD_FILE, null, null,
          MSGID_DESCRIPTION_KEYSTOREPASSWORD_FILE);
      argParser.addArgument(keyStorePasswordFileArg);
      certNicknameArg = new StringArgument("certnickname", 'N', "certNickname",
          false, false, true, "{nickname}", null, null,
          MSGID_DESCRIPTION_CERT_NICKNAME);
      argParser.addArgument(certNicknameArg);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
          OPTION_LONG_HELP,
          MSGID_DESCRIPTION_USAGE);
@@ -244,6 +376,46 @@
      }
    }
    // Couldn't have at the same time trustAll and
    // trustStore related arg
    if (trustAllArg.isPresent() && trustStorePathArg.isPresent())
    {
      int msgID = MSGID_TOOL_CONFLICTING_ARGS;
      errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(),
          trustStorePathArg.getLongIdentifier()));
    }
    if (trustAllArg.isPresent() && trustStorePasswordArg.isPresent())
    {
      int msgID = MSGID_TOOL_CONFLICTING_ARGS;
      errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(),
          trustStorePasswordArg.getLongIdentifier()));
    }
    if (trustAllArg.isPresent() && trustStorePasswordFileArg.isPresent())
    {
      int msgID = MSGID_TOOL_CONFLICTING_ARGS;
      errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(),
          trustStorePasswordFileArg.getLongIdentifier()));
    }
    // Couldn't have at the same time trustStorePasswordArg and
    // trustStorePasswordFileArg
    if (trustStorePasswordArg.isPresent()
        && trustStorePasswordFileArg.isPresent())
    {
      int msgID = MSGID_TOOL_CONFLICTING_ARGS;
      errors.add(getMessage(msgID, trustStorePasswordArg
          .getLongIdentifier(), trustStorePasswordFileArg.getLongIdentifier()));
    }
    // Couldn't have at the same time startTLSArg and
    // useSSLArg
    if (startTLSArg.isPresent()
        && useSSLArg.isPresent())
    {
      int msgID = MSGID_TOOL_CONFLICTING_ARGS;
      errors.add(getMessage(msgID, startTLSArg.getLongIdentifier(),
          useSSLArg.getLongIdentifier()));
    }
    if (errors.size() > 0)
    {
      System.err.println(Utils.getStringFromCollection(errors,
@@ -264,29 +436,50 @@
      ServerStatusDescriptor desc = createServerStatusDescriptor(
      directoryManagerDn, directoryManagerPwd);
      if (isServerRunning)
      {
        String ldapUrl = offLineConf.getLDAPURL();
        if (directoryManagerDn == null)
        {
          directoryManagerDn = "";
        }
        if (directoryManagerPwd == null)
        {
          directoryManagerPwd = "";
        }
        ConfigFromLDAP onLineConf = new ConfigFromLDAP();
        onLineConf.setConnectionInfo(ldapUrl, directoryManagerDn,
            directoryManagerPwd);
        onLineConf.readConfiguration();
        updateDescriptorWithOnLineInfo(desc, onLineConf);
      }
      else
      {
        updateDescriptorWithOffLineInfo(desc, offLineConf);
      }
      writeStatus(desc);
      try
      {
        if (isServerRunning)
        {
          if (directoryManagerDn == null)
          {
            directoryManagerDn = "";
          }
          if (directoryManagerPwd == null)
          {
            directoryManagerPwd = "";
          }
          ConfigFromLDAP onLineConf = new ConfigFromLDAP();
          ConnectionProtocolPolicy policy;
          if (startTLSArg.isPresent())
          {
            policy = ConnectionProtocolPolicy.USE_STARTTLS;
          }
          if (useSSLArg.isPresent())
          {
            policy = ConnectionProtocolPolicy.USE_LDAPS;
          }
          else
          {
            policy = ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE;
          }
          onLineConf.setConnectionInfo(offLineConf, policy, directoryManagerDn,
              directoryManagerPwd, getTrustManager());
          onLineConf.readConfiguration();
          // TO COMPLETE: check the certificates
          updateDescriptorWithOnLineInfo(desc, onLineConf);
        }
        else
        {
          updateDescriptorWithOffLineInfo(desc, offLineConf);
        }
        writeStatus(desc);
      }
      catch (ConfigException ce)
      {
        System.err.println(wrap(ce.getMessage()));
      }
    }
    return returnValue;
@@ -1060,5 +1253,165 @@
    }
    return centered;
  }
  /**
   * Handle TrustStore.
   *
   * @return The trustStore manager to be used for the command.
   */
 public ApplicationTrustManager getTrustManager()
 {
   ApplicationTrustManager truststoreManager = null ;
   KeyStore truststore = null ;
   if (trustAllArg.isPresent())
   {
     // Running a null TrustManager  will force createLdapsContext and
     // createStartTLSContext to use a bindTrustManager.
     return null ;
   }
   else
   if (trustStorePathArg.isPresent())
   {
     try
     {
       FileInputStream fos = new FileInputStream(trustStorePathArg.getValue());
       String trustStorePasswordStringValue = null;
       char[] trustStorePasswordValue = null;
       if (trustStorePasswordArg.isPresent())
       {
         trustStorePasswordStringValue = trustStorePasswordArg.getValue();
       }
       else if (trustStorePasswordFileArg.isPresent())
       {
         trustStorePasswordStringValue = trustStorePasswordFileArg.getValue();
       }
       if (trustStorePasswordStringValue !=  null)
       {
         trustStorePasswordStringValue = System
             .getProperty("javax.net.ssl.trustStorePassword");
       }
       if (trustStorePasswordStringValue !=  null)
       {
         trustStorePasswordValue = trustStorePasswordStringValue.toCharArray();
       }
       truststore = KeyStore.getInstance(KeyStore.getDefaultType());
       truststore.load(fos, trustStorePasswordValue);
       fos.close();
     }
     catch (KeyStoreException e)
     {
       // Nothing to do: if this occurs we will systematically refuse the
       // certificates.  Maybe we should avoid this and be strict, but we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the truststore", e);
     }
     catch (NoSuchAlgorithmException e)
     {
       // Nothing to do: if this occurs we will systematically refuse the
       // certificates.  Maybe we should avoid this and be strict, but we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the truststore", e);
     }
     catch (CertificateException e)
     {
       // Nothing to do: if this occurs we will systematically refuse the
       // certificates.  Maybe we should avoid this and be strict, but we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the truststore", e);
     }
     catch (IOException e)
     {
       // Nothing to do: if this occurs we will systematically refuse the
       // certificates.  Maybe we should avoid this and be strict, but we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the truststore", e);
     }
   }
   truststoreManager = new ApplicationTrustManager(truststore);
   return truststoreManager;
 }
 /**
  * Handle KeyStore.
  *
  * @return The keyStore manager to be used for the command.
  */
 public KeyManager getKeyManager()
 {
   KeyStore keyStore = null;
   String keyStorePasswordValue = null;
   if (keyStorePathArg.isPresent())
   {
     try
     {
       FileInputStream fos = new FileInputStream(keyStorePathArg.getValue());
       if (keyStorePasswordArg.isPresent())
       {
         keyStorePasswordValue = keyStorePasswordArg.getValue();
       }
       else if (keyStorePasswordFileArg.isPresent())
       {
         keyStorePasswordValue = keyStorePasswordFileArg.getValue();
       }
       keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
       keyStore.load(fos, keyStorePasswordValue.toCharArray());
     }
     catch (KeyStoreException e)
     {
       // Nothing to do: if this occurs we will systematically refuse
       // the
       // certificates. Maybe we should avoid this and be strict, but
       // we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the keystore", e);
     }
     catch (NoSuchAlgorithmException e)
     {
       // Nothing to do: if this occurs we will systematically refuse
       // the
       // certificates. Maybe we should avoid this and be strict, but
       // we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the keystore", e);
     }
     catch (CertificateException e)
     {
       // Nothing to do: if this occurs we will systematically refuse
       // the
       // certificates. Maybe we should avoid this and be strict, but
       // we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the keystore", e);
     }
     catch (IOException e)
     {
       // Nothing to do: if this occurs we will systematically refuse
       // the
       // certificates. Maybe we should avoid this and be strict, but
       // we are
       // in a best effor mode.
       LOG.log(Level.WARNING, "Error with the keystore", e);
     }
     ApplicationKeyManager akm = new ApplicationKeyManager(keyStore,
         keyStorePasswordValue.toCharArray());
     if (certNicknameArg.isPresent())
     {
       return new SelectableCertificateKeyManager(akm, certNicknameArg
           .getValue());
     }
     else
     {
       return akm;
     }
   }
   else
   {
     return null;
   }
 }
}
opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java
@@ -39,7 +39,9 @@
import org.opends.server.core.DirectoryServer;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.ui.ProgressDialog;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.util.BackgroundTask;
@@ -51,7 +53,6 @@
import org.opends.statuspanel.event.StatusPanelButtonListener;
import org.opends.statuspanel.i18n.ResourceProvider;
import org.opends.statuspanel.ui.LoginDialog;
import org.opends.statuspanel.ui.ProgressDialog;
import org.opends.statuspanel.ui.StatusPanelDialog;
/**
@@ -86,9 +87,14 @@
  private Thread progressUpdater;
  private ApplicationTrustManager trustManager;
//Update period of the progress dialog.
  private static final int UPDATE_PERIOD = 500;
  private static final ConnectionProtocolPolicy CONNECTION_POLICY =
    ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE;
  /**
   * This method creates the control panel dialogs and to check the current
   * install status. This method must be called outside the event thread because
@@ -108,11 +114,12 @@
  {
    DirectoryServer.bootstrapClient();
    initLookAndFeel();
    trustManager = new ApplicationTrustManager(null);
    /* Call this methods to create the dialogs (the control panel dialog
     * is generated when we call getLoginDialog()). */
    getLoginDialog();
    getProgressDialog();
    serverStatusPooler = new ServerStatusPooler();
    serverStatusPooler = new ServerStatusPooler(CONNECTION_POLICY);
    serverStatusPooler.addServerStatusChangeListener(this);
    serverStatusPooler.startPooling();
    desc = serverStatusPooler.getLastDescriptor();
@@ -445,9 +452,19 @@
    getLoginDialog().setVisible(true);
    if (!getLoginDialog().isCancelled())
    {
      serverStatusPooler.setAuthentication(
          getLoginDialog().getDirectoryManagerDn(),
          getLoginDialog().getDirectoryManagerPwd());
      try
      {
        serverStatusPooler.setAuthentication(
            getLoginDialog().getDirectoryManagerDn(),
            getLoginDialog().getDirectoryManagerPwd(),
            trustManager);
      }
      catch (ConfigException ce)
      {
        Utilities.displayError(getLoginDialog(), ce.getMessage(),
            getMsg("error-title"));
        getLoginDialog().toFront();
      }
    }
  }
@@ -468,7 +485,8 @@
  {
    if (loginDialog == null)
    {
      loginDialog = new LoginDialog(getStatusPanelDialog());
      loginDialog = new LoginDialog(getStatusPanelDialog(), trustManager,
          CONNECTION_POLICY);
      loginDialog.setModal(true);
    }
    return loginDialog;
@@ -819,10 +837,10 @@
   * This method is used to update the progress dialog.
   *
   * We are receiving notifications from the installer and uninstaller (this
   * class is a ProgressListener). However if we lots of notifications updating
   * the progress panel every time we get a progress update can result of a lot
   * of flickering. So the idea here is to have a minimal time between 2 updates
   * of the progress dialog (specified by UPDATE_PERIOD).
   * class is a ProgressListener). However if we send lots of notifications
   * updating the progress panel every time we get a progress update can result
   * of a lot of flickering. So the idea here is to have a minimal time between
   * 2 updates of the progress dialog (specified by UPDATE_PERIOD).
   */
  private void runProgressUpdater()
  {
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -101,33 +101,18 @@
undefined-protocol-label=-Unknown-
error-reading-config-file=Error reading the configuration file.
could-not-find-valid-ldapurl=Error reading the configuration file.\n\
This could be caused because there is not an enabled LDAP port to retrieve \
monitoring information or because you do not have read rights on the \
This could be caused because there is not an enabled LDAP port for the \
specified connection parameters or because you do not have read rights on the \
configuration file.
number-entries-multiple-suffixes-in-db={0} (for all base DNs in {1})
error-reading-config-ldap=Error reading data from server.  Try \
re-authenticating.\nDetails: {0}
error-reading-config-ldap=Error reading data from server.  Verify the \
authentication information provided.\nDetails: {0}
no-dbs-found=-No LDAP Databases Found-
no-listeners-found=-No Listener Ports Found-
suffix-replicated-label=Enabled
suffix-not-replicated-label=Disabled
#
# Progress Dialog
#
close-progress-button-tooltip=Close Progress Dialog
progress-title=Progress
summary-starting=Starting Server...
summary-stopping=Stopping Server...
summary-start-error=An error occurred Starting Server.  Check 'Details' text \
area for more information.
summary-stop-error=An error occurred Stopping Server.  Check 'Details' text \
area for more information.
error-starting-server-code=Error Starting Directory Server.  Error code: {0}.
summary-start-success=OpenDS Started Successfully.
summary-stop-success=OpenDS Stopped Successfully.
#
# Confirmation messages
#
confirm-stop-message=Are you sure you want to Stop the Directory Server?
opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
@@ -32,9 +32,13 @@
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
@@ -46,16 +50,23 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.Step;
import org.opends.quicksetup.UserDataCertificateException;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.ui.CertificateDialog;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.util.BackgroundTask;
import org.opends.quicksetup.util.Utils;
import org.opends.statuspanel.ConfigException;
import org.opends.statuspanel.ConfigFromFile;
import org.opends.statuspanel.ConnectionProtocolPolicy;
import org.opends.statuspanel.i18n.ResourceProvider;
/**
@@ -65,7 +76,7 @@
 */
public class LoginDialog extends JDialog
{
  private static final long serialVersionUID = 9049409381101152000L;
  private static final long serialVersionUID = 9049606381601152500L;
  private JFrame parent;
@@ -82,16 +93,35 @@
  private ConfigFromFile conf;
  private ApplicationTrustManager trustManager;
  private ConnectionProtocolPolicy policy;
  private String usedUrl;
  private static final Logger LOG =
    Logger.getLogger(LoginDialog.class.getName());
  /**
   * Constructor of the LoginDialog.
   * @param parent the parent frame for this dialog.
   * @param trustManager the trust manager to be used for the secure
   * connections.
   * @param policy the configuration policy to be used (whether we prefer the
   * most secure, the less secure, a specific method...).
   */
  public LoginDialog(JFrame parent)
  public LoginDialog(JFrame parent, ApplicationTrustManager trustManager,
      ConnectionProtocolPolicy policy)
  {
    super(parent);
    setTitle(getMsg("login-dialog-title"));
    this.parent = parent;
    getContentPane().add(createPanel());
    if (trustManager == null)
    {
      throw new IllegalArgumentException("The trustmanager cannot be null.");
    }
    this.trustManager = trustManager;
    this.policy = policy;
    /*
     * TODO: find a way to calculate this dynamically.  This is done to avoid
     * all the text in a single line.
@@ -331,16 +361,97 @@
        InitialLdapContext ctx = null;
        try
        {
          String ldapUrl = getLDAPURL();
          if (ldapUrl != null)
          String ldapUrl = getConfig().getLDAPURL();
          String startTlsUrl = getConfig().getStartTLSURL();
          String ldapsUrl = getConfig().getLDAPSURL();
          switch (policy)
          {
            ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
          }
          else
          {
            throw new Error("could-not-find-valid-ldapurl");
          case USE_STARTTLS:
            if (startTlsUrl != null)
            {
              usedUrl = startTlsUrl;
              ctx = Utils.createStartTLSContext(startTlsUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
                  getTrustManager(), null);
            }
            else
            {
              throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
            }
            break;
          case USE_LDAPS:
            if (ldapsUrl != null)
            {
              usedUrl = ldapsUrl;
              ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
                  getTrustManager());
            }
            else
            {
              throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
            }
            break;
          case USE_LDAP:
            if (ldapUrl != null)
            {
              usedUrl = ldapUrl;
              ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
                    tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
            }
            else
            {
              throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
            }
            break;
          case USE_MOST_SECURE_AVAILABLE:
            if (ldapsUrl != null)
            {
              usedUrl = ldapsUrl;
              ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
                  getTrustManager());
            }
            else if (startTlsUrl != null)
            {
              usedUrl = startTlsUrl;
              ctx = Utils.createStartTLSContext(startTlsUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
                  getTrustManager(), null);
            }
            else if (ldapUrl != null)
            {
              usedUrl = ldapUrl;
              ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
                    tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
            }
            else
            {
              throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
            }
            break;
          case USE_LESS_SECURE_AVAILABLE:
            if (ldapUrl != null)
            {
              usedUrl = ldapUrl;
              ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
                    tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
            }
            else if (ldapsUrl != null)
            {
              usedUrl = ldapsUrl;
              ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
                  tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
                  getTrustManager());
            }
            else
            {
              throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
            }
            break;
            default:
              throw new IllegalStateException("Unknown connection policy: "+
                  policy);
          }
          /*
@@ -361,6 +472,9 @@
            throw ne;
          }
          isServerRunning = Boolean.FALSE;
        } catch (Error e)
        {
          throw e;
        } catch (IllegalStateException ise)
        {
          throw ise;
@@ -369,8 +483,9 @@
        {
          throw new IllegalStateException("Unexpected throwable.", t);
        }
        if (ctx != null)
        finally
        {
          if (ctx != null)
          try
          {
            ctx.close();
@@ -387,7 +502,59 @@
      {
        if (throwable != null)
        {
          if (throwable instanceof NamingException)
          LOG.log(Level.INFO, "Error connecting: " + throwable, throwable);
          if (Utils.isCertificateException(throwable))
          {
            ApplicationTrustManager.Cause cause =
              trustManager.getLastRefusedCause();
            LOG.log(Level.INFO, "Certificate exception cause: "+cause);
            UserDataCertificateException.Type excType = null;
            if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED)
            {
              excType = UserDataCertificateException.Type.NOT_TRUSTED;
            }
            else if (cause ==
              ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)
            {
              excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH;
            }
            else
            {
              String msg = Utils.getThrowableMsg(getI18n(),
                  "error-connecting-to-local", null, throwable);
              displayError(msg, getMsg("error-title"));
            }
            if (excType != null)
            {
              String h;
              int p;
              try
              {
                URI uri = new URI(usedUrl);
                h = uri.getHost();
                p = uri.getPort();
              }
              catch (Throwable t)
              {
                LOG.log(Level.WARNING,
                    "Error parsing ldap url of ldap url.", t);
                h = getMsg("not-available-label");
                p = -1;
              }
              UserDataCertificateException udce =
              new UserDataCertificateException(Step.REPLICATION_OPTIONS,
                  getMsg("certificate-exception",
                      new String[] {h, String.valueOf(p)}),
                  throwable, h, p,
                  getTrustManager().getLastRefusedChain(),
                  getTrustManager().getLastRefusedAuthType(), excType);
              handleCertificateException(udce);
            }
          }
          else if (throwable instanceof NamingException)
          {
            boolean dnInvalid = false;
            boolean pwdInvalid = false;
@@ -463,7 +630,7 @@
                  getMsg("error-title"));
            }
          }
          else if (throwable instanceof Error)
          else if (throwable instanceof ConfigException)
          {
            displayError(throwable.getMessage(), getMsg("error-title"));
          }
@@ -550,17 +717,6 @@
  }
  /**
   * Returns the ldap URL used to log into the server based in the contents
   * of the config file.
   * @return the ldap URL used to log into the server based in the contents
   * of the config file.
   */
  private String getLDAPURL()
  {
    return getConfig().getLDAPURL();
  }
  /**
   * Returns the ConfigFromFile object that contains the configuration read
   * from the config file.
   * @return the ConfigFromFile object that contains the configuration read
@@ -594,6 +750,66 @@
  }
  /**
   * Returns the trust manager that can be used to establish secure connections.
   * @return the trust manager that can be used to establish secure connections.
   */
  private ApplicationTrustManager getTrustManager()
  {
    return trustManager;
  }
  /**
   * Displays a dialog asking the user to accept a certificate if the user
   * accepts it, we update the trust manager and simulate a click on "OK" to
   * re-check the authentication.
   * This method assumes that we are being called from the event thread.
   */
  private void handleCertificateException(UserDataCertificateException ce)
  {
    CertificateDialog dlg = new CertificateDialog(parent, ce);
    dlg.pack();
    dlg.setVisible(true);
    if (dlg.isAccepted())
    {
      X509Certificate[] chain = ce.getChain();
      String authType = ce.getAuthType();
      String host = ce.getHost();
      if ((chain != null) && (authType != null) && (host != null))
      {
        LOG.log(Level.INFO, "Accepting certificate presented by host "+host);
        getTrustManager().acceptCertificate(chain, authType, host);
        /* Simulate a click on the OK */
        SwingUtilities.invokeLater(new Runnable()
        {
          public void run()
          {
            okButton.doClick();
          }
        });
      }
      else
      {
        if (chain == null)
        {
          LOG.log(Level.WARNING,
              "The chain is null for the UserDataCertificateException");
        }
        if (authType == null)
        {
          LOG.log(Level.WARNING,
              "The auth type is null for the UserDataCertificateException");
        }
        if (host == null)
        {
          LOG.log(Level.WARNING,
              "The host is null for the UserDataCertificateException");
        }
      }
    }
  }
  /**
   * Method written for testing purposes.
   * @param args the arguments to be passed to the test program.
   */
@@ -602,7 +818,9 @@
    try
    {
      // UIFactory.initialize();
      LoginDialog dlg = new LoginDialog(new JFrame());
      LoginDialog dlg = new LoginDialog(new JFrame(),
          new ApplicationTrustManager(null),
          ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE);
      dlg.pack();
      dlg.setVisible(true);
    } catch (Exception ex)