From 569de0b5cfe57748ec244ee19846ce34d0837a1e Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 30 Jul 2010 13:40:30 +0000
Subject: [PATCH] Fix issue 4573 - Admin Connector certificate should use the host name provided by the user in setup. This is achieved by storing the specified hostname in a temporary file under cn=config, which will be used for generating the self-signed certificates and then deleted. If changing or deleting the self-signed certificates, the provided host name is lost and must be manually specified again.

---
 opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java    |   10 +-
 opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java          |    8 ++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java   |   99 ++++++++++++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/admin/AdministrationConnector.java |    8 +
 opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java               |   77 ++++++++++++++++++
 5 files changed, 190 insertions(+), 12 deletions(-)

diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index e682883..2f89801 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -26,7 +26,9 @@
  */
 package org.opends.quicksetup.installer;
 
+import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.net.URI;
 import java.util.*;
@@ -165,7 +167,7 @@
   protected Set<InstallProgressStep>
           completedProgress = new HashSet<InstallProgressStep>();
 
-  private List<WizardStep> lstSteps = new ArrayList<WizardStep>();
+  private final List<WizardStep> lstSteps = new ArrayList<WizardStep>();
 
   private final HashSet<WizardStep> SUBSTEPS = new HashSet<WizardStep>();
   {
@@ -175,7 +177,7 @@
     SUBSTEPS.add(Step.REMOTE_REPLICATION_PORTS);
   }
 
-  private HashMap<WizardStep, WizardStep> hmPreviousSteps =
+  private final HashMap<WizardStep, WizardStep> hmPreviousSteps =
     new HashMap<WizardStep, WizardStep>();
 
   private char[] selfSignedCertPw = null;
@@ -232,6 +234,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean isCancellable() {
     return true;
   }
@@ -239,6 +242,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public UserData createUserData() {
     UserData ud = new UserData();
     ud.setServerLocation(getDefaultServerLocation());
@@ -273,6 +277,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void forceToDisplay() {
     forceToDisplaySetup = true;
   }
@@ -280,6 +285,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean canGoBack(WizardStep step) {
     return step != WELCOME &&
             step != PROGRESS &&
@@ -289,6 +295,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean canGoForward(WizardStep step) {
     return step != REVIEW &&
             step != PROGRESS &&
@@ -298,6 +305,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean canFinish(WizardStep step) {
     return step == REVIEW;
   }
@@ -305,6 +313,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean canQuit(WizardStep step) {
     return step != PROGRESS &&
     step != FINISHED;
@@ -313,6 +322,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean isSubStep(WizardStep step)
   {
     return SUBSTEPS.contains(step);
@@ -321,6 +331,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean isVisible(WizardStep step, UserData userData)
   {
     boolean isVisible;
@@ -373,6 +384,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean isVisible(WizardStep step, QuickSetup qs)
   {
     return isVisible(step, getUserData());
@@ -381,6 +393,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean finishClicked(final WizardStep cStep, final QuickSetup qs) {
     if (cStep == Step.REVIEW) {
         updateUserDataForReviewPanel(qs);
@@ -397,6 +410,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void nextClicked(WizardStep cStep, QuickSetup qs) {
     if (cStep == PROGRESS) {
       throw new IllegalStateException(
@@ -412,6 +426,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void closeClicked(WizardStep cStep, QuickSetup qs) {
     if (cStep == PROGRESS) {
       if (isFinished()
@@ -432,6 +447,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean isFinished()
   {
     return getCurrentProgressStep() == InstallProgressStep.FINISHED_SUCCESSFULLY
@@ -442,6 +458,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void cancel() {
     setCurrentProgressStep(InstallProgressStep.WAITING_TO_CANCEL);
     notifyListeners(null);
@@ -451,6 +468,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void quitClicked(WizardStep cStep, QuickSetup qs) {
     if (cStep == FINISHED)
     {
@@ -475,6 +493,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public ButtonName getInitialFocusButtonName() {
     ButtonName name = null;
     if (!installStatus.isInstalled() || forceToDisplaySetup)
@@ -497,6 +516,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public JPanel createFramePanel(QuickSetupDialog dlg) {
     JPanel p;
     javaVersionCheckFailed = true;
@@ -542,6 +562,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Set<? extends WizardStep> getWizardSteps() {
     return Collections.unmodifiableSet(new HashSet<WizardStep>(lstSteps));
   }
@@ -549,6 +570,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public QuickSetupStepPanel createWizardStepPanel(WizardStep step) {
     QuickSetupStepPanel p = null;
     if (step == WELCOME) {
@@ -582,6 +604,7 @@
   /**
   * {@inheritDoc}
   */
+  @Override
   public void windowClosing(QuickSetupDialog dlg, WindowEvent evt) {
 
     if (installStatus.isInstalled() && forceToDisplaySetup) {
@@ -601,6 +624,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Message getCloseButtonToolTip() {
     return INFO_CLOSE_BUTTON_INSTALL_TOOLTIP.get();
   }
@@ -608,6 +632,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Message getQuitButtonToolTip() {
     return INFO_QUIT_BUTTON_INSTALL_TOOLTIP.get();
   }
@@ -615,6 +640,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Message getFinishButtonToolTip() {
     return INFO_FINISH_BUTTON_INSTALL_TOOLTIP.get();
   }
@@ -622,6 +648,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public int getExtraDialogHeight() {
     return UIFactory.EXTRA_DIALOG_HEIGHT;
   }
@@ -629,6 +656,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void previousClicked(WizardStep cStep, QuickSetup qs) {
     if (cStep == WELCOME) {
       throw new IllegalStateException(
@@ -645,6 +673,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Message getFrameTitle() {
     return Utils.getCustomizedObject("INFO_FRAME_INSTALL_TITLE",
         INFO_FRAME_INSTALL_TITLE.get(DynamicConstants.PRODUCT_NAME),
@@ -658,6 +687,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void setWizardDialogState(QuickSetupDialog dlg,
                                       UserData userData,
                                       WizardStep step) {
@@ -681,6 +711,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public ProgressStep getCurrentProgressStep()
   {
     return currentProgressStep;
@@ -689,6 +720,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public WizardStep getFirstWizardStep() {
     return WELCOME;
   }
@@ -696,6 +728,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public WizardStep getNextWizardStep(WizardStep step) {
     WizardStep next = null;
     if (step == Step.REPLICATION_OPTIONS)
@@ -760,6 +793,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public LinkedHashSet<WizardStep> getOrderedSteps()
   {
     LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
@@ -783,6 +817,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public WizardStep getPreviousWizardStep(WizardStep step) {
     //  Try with the steps calculated in method getNextWizardStep.
     WizardStep prev = hmPreviousSteps.get(step);
@@ -800,6 +835,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public WizardStep getFinishedStep() {
     return Step.FINISHED;
   }
@@ -860,6 +896,8 @@
 
     writeOpenDSJavaHome();
 
+    writeHostName();
+
     if (Utils.isWebStart())
     {
       String installDir = getUserData().getServerLocation();
@@ -1024,6 +1062,7 @@
     setNotifyListeners(false);
     InvokeThread thread = new InvokeThread()
     {
+      @Override
       public void run()
       {
         int result = -1;
@@ -1058,6 +1097,7 @@
         }
         isOver = true;
       }
+      @Override
       public void abort()
       {
         // TODO: implement the abort
@@ -1279,6 +1319,7 @@
 
     InvokeThread thread = new InvokeThread()
     {
+      @Override
       public void run()
       {
         try
@@ -1303,6 +1344,7 @@
         }
         isOver = true;
       }
+      @Override
       public void abort()
       {
         // TODO: implement the abort
@@ -1387,6 +1429,7 @@
 
     InvokeThread thread = new InvokeThread()
     {
+      @Override
       public void run()
       {
         try
@@ -1416,6 +1459,7 @@
         }
         isOver = true;
       }
+      @Override
       public void abort()
       {
         // TODO: implement the abort
@@ -1501,6 +1545,7 @@
 
     InvokeThread thread = new InvokeThread()
     {
+      @Override
       public void run()
       {
         try
@@ -1536,6 +1581,7 @@
         }
         isOver = true;
       }
+      @Override
       public void abort()
       {
         // TODO: implement the abort
@@ -2232,6 +2278,7 @@
    *
    * @throws ApplicationException thrown if <code>canceled</code>
    */
+  @Override
   public void checkAbort() throws ApplicationException {
     if (canceled) {
       setCurrentProgressStep(InstallProgressStep.CANCELING);
@@ -2243,12 +2290,55 @@
   }
 
   /**
+   * Writes the host name to a file that will be used by the server to generate
+   * a self-signed certificate.
+   */
+  private void writeHostName()
+  {
+    BufferedWriter writer = null;
+    try
+    {
+      writer = new BufferedWriter(new FileWriter(getHostNameFile(), false));
+      writer.append(getUserData().getHostName());
+    }
+    catch (IOException ioe)
+    {
+      LOG.log(Level.WARNING, "Error writing host name file: "+ioe, ioe);
+    }
+    finally
+    {
+      try
+      {
+        if (writer != null)
+        {
+          writer.close();
+        }
+      }
+      catch (Exception ex)
+      {
+      }
+    }
+  }
+
+  /**
+   * Returns the file path where the host name is to be written.
+   * @return the file path where the host name is to be written.
+   */
+  private String getHostNameFile()
+  {
+    String file = Utils.getPath(
+        getInstallation().getRootDirectory().getAbsolutePath(),
+        SetupUtils.HOST_NAME_FILE);
+    return file;
+  }
+
+  /**
    * Writes the java home that we are using for the setup in a file.
    * This way we can use this java home even if the user has not set
    * OPENDS_JAVA_HOME when running the different scripts.
    *
    */
-  protected void writeOpenDSJavaHome()
+  private void writeOpenDSJavaHome()
   {
     try
     {
@@ -2272,6 +2362,7 @@
    *           valid.
    *
    */
+  @Override
   public void updateUserData(WizardStep cStep, QuickSetup qs)
           throws UserDataException
   {
@@ -5065,6 +5156,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   protected void applicationPrintStreamReceived(String message)
   {
     InstallerHelper helper = new InstallerHelper();
@@ -5117,6 +5209,7 @@
   /**
    * Runnable implementation.
    */
+  @Override
   public abstract void run();
 
   /**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/AdministrationConnector.java b/opendj-sdk/opends/src/server/org/opends/server/admin/AdministrationConnector.java
index 58c5bc2..2bd247a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/AdministrationConnector.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/AdministrationConnector.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.admin;
 
@@ -62,6 +62,7 @@
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.ResultCode;
 import org.opends.server.util.CertificateManager;
+import org.opends.server.util.SetupUtils;
 import org.opends.server.admin.std.server.TrustManagerProviderCfg;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.ErrorLogger;
@@ -69,7 +70,6 @@
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.FilePermission;
-import org.opends.server.util.SetupUtils;
 
 /**
  * This class is a wrapper on top of LDAPConnectionHandler to manage
@@ -690,8 +690,10 @@
       CertificateManager certManager = new CertificateManager(
           getFullPath(fbKeyManagerConfig.getKeyStoreFile()), fbKeyManagerConfig
               .getKeyStoreType(), pwd);
+      String hostName =
+        SetupUtils.getHostNameForCertificate(DirectoryServer.getServerRoot());
       String subjectDN = "cn="
-          + Rdn.escapeValue(InetAddress.getLocalHost().getHostName()) + ",O="
+          + Rdn.escapeValue(hostName) + ",O="
           + FRIENDLY_NAME + " Self-Signed Certificate";
       certManager.generateSelfSignedCertificate(certAlias, subjectDN,
           ADMIN_CERT_VALIDITY);
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
index abceec1..7cd1125 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2007-2008 Sun Microsystems, Inc.
+ *      Copyright 2007-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.backends;
 
@@ -77,6 +77,7 @@
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.*;
 import org.opends.server.util.CertificateManager;
+import org.opends.server.util.SetupUtils;
 import org.opends.server.util.Validator;
 
 
@@ -1730,9 +1731,9 @@
   private static String getADSCertificateSubjectDN()
        throws UnknownHostException
   {
-    String hostname =
-         java.net.InetAddress.getLocalHost().getCanonicalHostName();
-    return "cn=" + Rdn.escapeValue(hostname) + ",O=OpenDS Certificate";
+    String hostName =
+      SetupUtils.getHostNameForCertificate(DirectoryServer.getServerRoot());
+    return "cn=" + Rdn.escapeValue(hostName) + ",O=OpenDS Certificate";
   }
 
   /**
@@ -1874,6 +1875,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 1cf51cf..fc9c4ce 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -1576,6 +1576,14 @@
       {
         serverStartingFile.delete();
       }
+
+      // If a host name file exists, then remove it.
+      File hostNameFile = new File(configHandler.getInstanceRoot() +
+          File.separator + SetupUtils.HOST_NAME_FILE);
+      if (hostNameFile.exists())
+      {
+        hostNameFile.delete();
+      }
     }
   }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java b/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
index b91ff88..b3268b3 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
@@ -22,20 +22,22 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.util;
 
 
-
+import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.UnknownHostException;
 import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
@@ -44,6 +46,7 @@
 import java.util.Set;
 
 import java.util.Random;
+
 import org.opends.server.types.OperatingSystem;
 
 
@@ -94,6 +97,14 @@
    */
   public static final String LIBRARIES_PATH_RELATIVE = "lib";
 
+  /**
+   * The relative path where the setup stores the name of the host the user
+   * provides. This is used for instance to generate the self-signed admin
+   * certificate the first time the server starts.
+   */
+  public static final String HOST_NAME_FILE = "config" + File.separatorChar
+      + "hostname";
+
   /* These string values must be synchronized with Directory Server's main
    * method.  These string values are considered stable by the server team and
    * not candidates for internationalization. */
@@ -135,6 +146,12 @@
   public static final String BUILD_NUMBER = "Build Number";
 
   /**
+   * A variable used to keep the latest read host name from the file written
+   * by the setup.
+   */
+  private static String lastReadHostName;
+
+  /**
    * Creates a MakeLDIF template file using the provided information.
    *
    * @param  baseDN      The base DN for the data in the template file.
@@ -635,5 +652,61 @@
     return (random.nextInt() & modulo);
   }
 
+  /**
+   * Returns the host name to be used to create self-signed certificates. <br>
+   * The method will first try to read the host name file written by the setup
+   * where the user provided the host name where OpenDS has been installed. If
+   * the file cannot be read, the class {@link java.net.InetAddress} is used.
+   *
+   * @param installationRoot the path where the server is installed.
+   * @return the host name to be used to create self-signed certificates.
+   * @throws UnknownHostException
+   *           if a host name could not be used.
+   */
+  public static String getHostNameForCertificate(
+      String installationRoot) throws UnknownHostException
+  {
+    String hostName = null;
+    File f = new File(installationRoot + File.separator + HOST_NAME_FILE);
+    BufferedReader br = null;
+    try
+    {
+      br = new BufferedReader(new FileReader(f));
+      String s = br.readLine();
+      s = s.trim();
+
+      if (s.length() > 0)
+      {
+        hostName = s;
+        lastReadHostName = hostName;
+      }
+    }
+    catch (IOException ioe)
+    {
+    }
+    finally
+    {
+      try
+      {
+        if (br != null)
+        {
+          br.close();
+        }
+      }
+      catch (Exception e)
+      {
+        // ignore
+      }
+    }
+    if (hostName == null)
+    {
+      hostName = lastReadHostName;
+    }
+    if (hostName == null)
+    {
+      hostName = java.net.InetAddress.getLocalHost().getHostName();
+    }
+    return hostName;
+  }
 }
 

--
Gitblit v1.10.0