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

Matthew Swift
25.52.2011 4ba18bd84e711f2a77f1de9b66fb9b52730d1d46
Fix OPENDJ-363: Make it more obvious in the setup tool that the fully-qualified hostname is critical for all secured connections

* improved heuristic for determining a default fully qualified host name. Reverse DNS lookups timeout after 1 second in order to avoid long delays if DNS is broken
* changed usage for host name which makes it clearer that the host name is required regardless of LDAPS/StartTLS configuration
* changed interactive CLI so that it always prompts for the fully qualified hostname
* changed the setup tool to make it clearer that it is prompting for the fully qualified hostname.

Tested on laptop with DNS and VM without DNS.
5 files modified
161 ■■■■ changed files
opends/src/messages/messages/quicksetup.properties 4 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/tools.properties 14 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 121 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/InstallDS.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java 4 ●●●● patch | view | raw | blame | history
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:
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 \
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;
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(),
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);