From 4ba18bd84e711f2a77f1de9b66fb9b52730d1d46 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 25 Nov 2011 20:52:47 +0000
Subject: [PATCH] Fix OPENDJ-363: Make it more obvious in the setup tool that the fully-qualified hostname is critical for all secured connections

---
 opends/src/server/org/opends/server/tools/InstallDS.java               |   18 ++----
 opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java |    4 
 opends/src/messages/messages/quicksetup.properties                     |    4 
 opends/src/messages/messages/tools.properties                          |   14 ++--
 opends/src/quicksetup/org/opends/quicksetup/UserData.java              |  121 +++++++++++++++++++++++++++++++++++++--
 5 files changed, 131 insertions(+), 30 deletions(-)

diff --git a/opends/src/messages/messages/quicksetup.properties b/opends/src/messages/messages/quicksetup.properties
index 8189444..63c9494 100644
--- a/opends/src/messages/messages/quicksetup.properties
+++ b/opends/src/messages/messages/quicksetup.properties
@@ -547,7 +547,7 @@
 INFO_HELP_WAIT_DESCRIPTION=Busy, please wait.
 INFO_HIDE_DETAILS_BUTTON_LABEL=Hide Details
 INFO_HIDE_EXCEPTION_DETAILS=Hide Details
-INFO_HOST_NAME_LABEL=Host Name:
+INFO_HOST_NAME_LABEL=Fully Qualified Host Name:
 INFO_HOST_NAME_TOOLTIP=Enter the fully qualified name of the local host.
 # Only translate if the color is specific to the local
 INFO_HTML_SEPARATOR_COLOR=666666
@@ -823,7 +823,7 @@
 INFO_REMOTE_SERVER_DN_LABEL=Admin User:
 INFO_REMOTE_SERVER_DN_TOOLTIP=The DN or the UID of an administrator in the \
  server you want to replicate data with.
-INFO_REMOTE_SERVER_HOST_LABEL=Host Name:
+INFO_REMOTE_SERVER_HOST_LABEL=Fully Qualified Host Name:
 INFO_REMOTE_SERVER_HOST_TOOLTIP=The fully qualified name of the host where \
  the server you want to replicate data with is located.
 INFO_REMOTE_SERVER_PORT_LABEL=Administration Connector Port:
diff --git a/opends/src/messages/messages/tools.properties b/opends/src/messages/messages/tools.properties
index 6eb32e7..235cfbd 100644
--- a/opends/src/messages/messages/tools.properties
+++ b/opends/src/messages/messages/tools.properties
@@ -2550,12 +2550,14 @@
  argument '%s'
 INFO_DESCRIPTION_SUBENTRIES_1702=Use subentries control to specify that \
  subentries are visible and normal entries are not
-INFO_INSTALLDS_DESCRIPTION_HOST_NAME_1703=Directory server host name or IP \
- address that will be used to generate the self-signed certificate.  This \
- argument will be taken into account only if the self-signed certificate \
- argument %s is specified
-INFO_INSTALLDS_PROMPT_HOST_NAME_1704=Provide the fully-qualified host name or \
- IP address that will be used to generate the self-signed certificate
+INFO_INSTALLDS_DESCRIPTION_HOST_NAME_1703=The fully-qualified directory server \
+ host name that will be used when generating self-signed \
+ certificates for LDAP SSL/StartTLS, the administration connector, and \
+ replication
+INFO_INSTALLDS_PROMPT_HOST_NAME_1704=Provide the fully-qualified directory server \
+ host name that will be used when generating self-signed \
+ certificates for LDAP SSL/StartTLS, the administration connector, and \
+ replication
 INFO_PERIOD_PLACEHOLDER_1705={period}
 INFO_DESCRIPTION_REFRESH_PERIOD_1706=When this argument is specified, the \
  status command will display its contents periodically.  Used to specify \
diff --git a/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 255a8d1..305be5f 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -23,15 +23,15 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.opends.quicksetup;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.opends.admin.ads.ServerDescriptor;
 import org.opends.admin.ads.SuffixDescriptor;
@@ -702,13 +702,118 @@
   {
     if (defaultHostName == null)
     {
+      // Run a thread in the background in order to avoid blocking the
+      // application if reverse DNS lookups take a long time.
+      final CountDownLatch latch = new CountDownLatch(1);
+      Thread t = new Thread(new Runnable()
+      {
+        // Search for a host name of the form host.example.com on each
+        // interface, except the loop back. Prefer interfaces of the form ethX.
+        public void run()
+        {
+          try
+          {
+            SortedMap<String, String> hostNames = new TreeMap<String, String>();
+            Enumeration<NetworkInterface> i = NetworkInterface
+                .getNetworkInterfaces();
+            while (i.hasMoreElements())
+            {
+              NetworkInterface n = i.nextElement();
+
+              // Skip loop back interface.
+              if (n.isLoopback())
+              {
+                continue;
+              }
+
+              // Check each interface address (IPv4 and IPv6).
+              String ipv4HostName = null;
+              String ipv6HostName = null;
+              Enumeration<InetAddress> j = n.getInetAddresses();
+              while (j.hasMoreElements())
+              {
+                InetAddress address = j.nextElement();
+                String hostAddress = address.getHostAddress();
+                String hostName = address.getCanonicalHostName();
+
+                // Ignore hostnames which are IP addresses.
+                if (!hostAddress.equals(hostName))
+                {
+                  if (address instanceof Inet4Address)
+                  {
+                    ipv4HostName = hostName;
+                  }
+                  else if (address instanceof Inet6Address)
+                  {
+                    ipv6HostName = hostName;
+                  }
+                }
+              }
+
+              // Remember the host name if it looks fully qualified.
+              String fqHostName = null;
+              if (ipv4HostName != null && ipv4HostName.contains("."))
+              {
+                fqHostName = ipv4HostName;
+              }
+              else if (ipv6HostName != null && ipv6HostName.contains("."))
+              {
+                fqHostName = ipv6HostName;
+              }
+
+              if (fqHostName != null)
+              {
+                hostNames.put(n.getName(), fqHostName);
+
+                // This looks like a fully qualified name on a ethX interface,
+                // so
+                // use that and break out.
+                if (n.getName().startsWith("eth"))
+                {
+                  defaultHostName = fqHostName;
+                  break;
+                }
+              }
+            }
+
+            if (defaultHostName == null && !hostNames.isEmpty())
+            {
+              // No ethX host name, so try any other host name that was found.
+              defaultHostName = hostNames.values().iterator().next();
+            }
+          }
+          catch (Exception e)
+          {
+            // Ignore - we'll default to the loopback address later.
+          }
+
+          latch.countDown();
+        }
+      });
+
       try
       {
-        defaultHostName = java.net.InetAddress.getLocalHost().getHostName();
+        t.setDaemon(true);
+        t.start();
+        latch.await(1, TimeUnit.SECONDS);
       }
-      catch (Throwable t)
+      catch (Exception e)
       {
-        defaultHostName = "localhost";
+        // Ignore - we'll default to the loopback address later.
+      }
+
+      if (defaultHostName == null)
+      {
+        // No host names found, so use the loop back.
+        try
+        {
+          defaultHostName = InetAddress.getLocalHost().getHostName();
+        }
+        catch (Exception e)
+        {
+          // Not much we can do here.
+          defaultHostName = "localhost";
+        }
       }
     }
     return defaultHostName;
diff --git a/opends/src/server/org/opends/server/tools/InstallDS.java b/opends/src/server/org/opends/server/tools/InstallDS.java
index 8ed2228..8c03770 100644
--- a/opends/src/server/org/opends/server/tools/InstallDS.java
+++ b/opends/src/server/org/opends/server/tools/InstallDS.java
@@ -1218,6 +1218,9 @@
    */
   private void promptIfRequiredForPortData(UserData uData)
   {
+    String hostName = promptForHostNameIfRequired();
+    uData.setHostName(hostName);
+
     LinkedList<Integer> usedPorts = new LinkedList<Integer>();
     //  Determine the LDAP port number.
     int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
@@ -1365,6 +1368,7 @@
     boolean prompt = true;
     if (!argParser.baseDNArg.isPresent())
     {
+      println();
       try
       {
         prompt = confirmAction(INFO_INSTALLDS_PROVIDE_BASE_DN_PROMPT.get(),
@@ -1765,8 +1769,6 @@
     {
       securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
           enableSSL, enableStartTLS, ldapsPort);
-      String hostName = promptForHostNameIfRequired();
-      uData.setHostName(hostName);
     }
     else if (argParser.useJavaKeyStoreArg.isPresent())
     {
@@ -1878,8 +1880,6 @@
         }
         if (certType == SELF_SIGNED)
         {
-          String hostName = promptForHostNameIfRequired();
-          uData.setHostName(hostName);
           securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
                 enableSSL, enableStartTLS, ldapsPort);
         }
@@ -2761,7 +2761,7 @@
     }
   }
 
-  private String promptForHostNameIfRequired() throws UserDataException
+  private String promptForHostNameIfRequired()
   {
     String hostName = null;
     if (argParser.hostNameArg.isPresent())
@@ -2770,15 +2770,9 @@
     }
     else
     {
-      int nTries = 0;
+      println();
       while (hostName == null)
       {
-        if (nTries >= CONFIRMATION_MAX_TRIES)
-        {
-          throw new UserDataException(null,
-              ERR_TRIES_LIMIT_REACHED.get(CONFIRMATION_MAX_TRIES));
-        }
-
         try
         {
           hostName = readInput(INFO_INSTALLDS_PROMPT_HOST_NAME.get(),
diff --git a/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java b/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
index 319d187..ebdc3d2 100644
--- a/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
+++ b/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 package org.opends.server.tools;
 
@@ -360,8 +361,7 @@
         OPTION_SHORT_HOST,
         OPTION_LONG_HOST, false, false, true, INFO_HOST_PLACEHOLDER.get(),
         UserData.getDefaultHostName(),
-        null, INFO_INSTALLDS_DESCRIPTION_HOST_NAME.get(
-            generateSelfSignedCertificateArg.getLongIdentifier()));
+        null, INFO_INSTALLDS_DESCRIPTION_HOST_NAME.get());
     hostNameArg.setPropertyName(OPTION_LONG_HOST);
     addDefaultArgument(hostNameArg);
 

--
Gitblit v1.10.0