From 7e6a2d6cd3a9b95acb001a3f37437893067bca27 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Mon, 30 Jul 2007 15:53:44 +0000
Subject: [PATCH] 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.

---
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigException.java             |   47 ++
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java          |   69 +-
 opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java |    2 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java                    |   13 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Configuration.java                 |   62 ++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Constants.java                     |    2 
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java              |  202 ++++++++
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java              |   92 +++
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java    |   53 ++
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java       |   38 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java                      |    2 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java             |    8 
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java                   |  399 ++++++++++++++++-
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java              |  270 ++++++++++-
 opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java                  |   24 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java                 |    2 
 opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties   |   23 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties     |   31 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java          |   15 
 19 files changed, 1,208 insertions(+), 146 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
index 8fcc2b7..c0c1aab 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
+++ b/opendj-sdk/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.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Configuration.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Configuration.java
index daa1859..3344898 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Configuration.java
+++ b/opendj-sdk/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.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Constants.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Constants.java
index b441f47..a227f07 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Constants.java
+++ b/opendj-sdk/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,
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 0ad6cd5..c6203ce 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opendj-sdk/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(
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index a39e139..691c68d 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/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
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
index 513869d..e7ab611 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
+++ b/opendj-sdk/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();
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/ProgressDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java
similarity index 97%
rename from opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/ProgressDialog.java
rename to opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java
index adc478c..f38ce4a 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/ProgressDialog.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/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();
   }
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
index 1f06876..d119114 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
+++ b/opendj-sdk/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.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 27c5846..0dd79b6 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opendj-sdk/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);
   }
 
   /**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
index ebd7aad..d7a2492 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
+++ b/opendj-sdk/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;
 
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigException.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigException.java
new file mode 100644
index 0000000..a247e27
--- /dev/null
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigException.java
@@ -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);
+  }
+}
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
index 95aaea3..538965e 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
+++ b/opendj-sdk/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));
+        }
+      }
+    }
   }
 
   /**
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
index d7b366b..c4e21b9 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
+++ b/opendj-sdk/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;
+  }
 }
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java
new file mode 100644
index 0000000..817cea9
--- /dev/null
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java
@@ -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,
+}
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java
index aed3f03..9652cbe 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java
+++ b/opendj-sdk/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;
       }
     }
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
index 9669f0b..97bef45 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
+++ b/opendj-sdk/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;
+   }
+ }
 }
 
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java
index f725f28..358690c 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java
+++ b/opendj-sdk/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()
   {
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
index 631c493..0256a03 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
+++ b/opendj-sdk/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?
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
index 4388dd8..56ef2c9 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
+++ b/opendj-sdk/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)

--
Gitblit v1.10.0