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

Gaetan Boismal
16.59.2016 1932d41262099a16f43749a90677366818b3664c
opendj-server-legacy/src/main/java/org/opends/guitools/uninstaller/UninstallCliHelper.java
@@ -791,39 +791,37 @@
    while (!couldConnect && accepted)
    {
      // This is done because we do not need to ask the user about these
      // parameters.  If we force their presence the class
      // LDAPConnectionConsoleInteraction will not prompt the user for
      // them.
      // This is done because we do not need to ask the user about these parameters.
      // If we force their presence the class LDAPConnectionConsoleInteraction will not prompt the user for them.
      SecureConnectionCliArgs secureArgsList = parser.getSecureArgsList();
      secureArgsList.hostNameArg.setPresent(true);
      secureArgsList.portArg.setPresent(true);
      secureArgsList.hostNameArg.clearValues();
      secureArgsList.hostNameArg.addValue(
          secureArgsList.hostNameArg.getDefaultValue());
      secureArgsList.portArg.clearValues();
      secureArgsList.portArg.addValue(
          secureArgsList.portArg.getDefaultValue());
      secureArgsList.bindDnArg.clearValues();
      secureArgsList.getHostNameArg().setPresent(true);
      secureArgsList.getPortArg().setPresent(true);
      secureArgsList.getHostNameArg().clearValues();
      secureArgsList.getHostNameArg().addValue(
          secureArgsList.getHostNameArg().getDefaultValue());
      secureArgsList.getPortArg().clearValues();
      secureArgsList.getPortArg().addValue(
          secureArgsList.getPortArg().getDefaultValue());
      secureArgsList.getBindDnArg().clearValues();
      if (uid != null)
      {
        secureArgsList.bindDnArg.addValue(ADSContext.getAdministratorDN(uid));
        secureArgsList.bindDnArg.setPresent(true);
        secureArgsList.getBindDnArg().addValue(ADSContext.getAdministratorDN(uid));
        secureArgsList.getBindDnArg().setPresent(true);
      }
      else
      {
        secureArgsList.bindDnArg.setPresent(false);
        secureArgsList.getBindDnArg().setPresent(false);
      }
      secureArgsList.bindPasswordArg.clearValues();
      secureArgsList.getBindPasswordArg().clearValues();
      if (pwd != null)
      {
        secureArgsList.bindPasswordArg.addValue(pwd);
        secureArgsList.bindPasswordArg.setPresent(true);
        secureArgsList.getBindPasswordArg().addValue(pwd);
        secureArgsList.getBindPasswordArg().setPresent(true);
      }
      else
      {
        secureArgsList.bindPasswordArg.setPresent(false);
        secureArgsList.getBindPasswordArg().setPresent(false);
      }
      if (ci == null)
@@ -853,8 +851,8 @@
        {
          URI uri = new URI(adminConnectorUrl);
          int port = uri.getPort();
          secureArgsList.portArg.clearValues();
          secureArgsList.portArg.addValue(String.valueOf(port));
          secureArgsList.getPortArg().clearValues();
          secureArgsList.getPortArg().addValue(String.valueOf(port));
          ci.setPortNumber(port);
        }
        catch (Throwable t)
@@ -1256,9 +1254,9 @@
        {
          println();
          printErrorMessage(ERR_UNINSTALL_ERROR_UPDATING_REMOTE_FORCE.get(
              "--"+parser.getSecureArgsList().adminUidArg.getLongIdentifier(),
              "--"+OPTION_LONG_BINDPWD,
              "--"+OPTION_LONG_BINDPWD_FILE,
              "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(),
              "--" + OPTION_LONG_BINDPWD,
              "--" + OPTION_LONG_BINDPWD_FILE,
              exceptionMsg));
        }
        else
@@ -1266,11 +1264,10 @@
          println();
          throw new UserDataException(null,
              ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get(
                  "--"+
                  parser.getSecureArgsList().adminUidArg.getLongIdentifier(),
                  "--"+OPTION_LONG_BINDPWD,
                  "--"+OPTION_LONG_BINDPWD_FILE,
                  "--"+parser.forceOnErrorArg.getLongIdentifier(),
                  "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(),
                  "--" + OPTION_LONG_BINDPWD,
                  "--" + OPTION_LONG_BINDPWD_FILE,
                  "--" + parser.forceOnErrorArg.getLongIdentifier(),
                  exceptionMsg));
        }
      }
@@ -1420,13 +1417,11 @@
        {
          LocalizableMessage msg =
            ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get(
              "--"+
              parser.getSecureArgsList().adminUidArg.getLongIdentifier(),
              "--"+OPTION_LONG_BINDPWD,
              "--"+OPTION_LONG_BINDPWD_FILE,
              "--"+parser.forceOnErrorArg.getLongIdentifier(),
              Utils.getMessageFromCollection(exceptionMsgs,
                  Constants.LINE_SEPARATOR));
              "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(),
              "--" + OPTION_LONG_BINDPWD,
              "--" + OPTION_LONG_BINDPWD_FILE,
              "--" + parser.forceOnErrorArg.getLongIdentifier(),
              Utils.getMessageFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR));
          throw new ClientException(ReturnCode.APPLICATION_ERROR, msg);
        }
      }
@@ -1549,7 +1544,7 @@
   {
     try
     {
       return parser.getSecureArgsList().connectTimeoutArg.getIntValue();
       return parser.getSecureArgsList().getConnectTimeoutArg().getIntValue();
     }
     catch (ArgumentException ae)
     {
opendj-server-legacy/src/main/java/org/opends/guitools/uninstaller/Uninstaller.java
@@ -1951,11 +1951,10 @@
        {
          LocalizableMessage msg =
            ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get(
              "--"+
              parser.getSecureArgsList().adminUidArg.getLongIdentifier(),
              "--"+OPTION_LONG_BINDPWD,
              "--"+OPTION_LONG_BINDPWD_FILE,
              "--"+parser.forceOnErrorArg.getLongIdentifier(),
              "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(),
              "--" + OPTION_LONG_BINDPWD,
              "--" + OPTION_LONG_BINDPWD_FILE,
              "--" + parser.forceOnErrorArg.getLongIdentifier(),
              ae.getMessageObject());
          throw new ApplicationException(ae.getType(), msg, ae);
        }
opendj-server-legacy/src/main/java/org/opends/guitools/uninstaller/UninstallerArgumentParser.java
@@ -25,6 +25,7 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
@@ -159,20 +160,20 @@
    quietArg = quietArgument();
    args.add(quietArg);
    ArrayList<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL));
    final List<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL));
    secureArgsList.createVisibleAdminUidArgument(INFO_DESCRIPTION_ADMIN_UID.get());
    int index = defaultArgs.indexOf(secureArgsList.bindDnArg);
    int index = defaultArgs.indexOf(secureArgsList.getBindDnArg());
    if (index != -1)
    {
      defaultArgs.add(index, secureArgsList.adminUidArg);
      defaultArgs.remove(secureArgsList.bindDnArg);
      defaultArgs.add(index, secureArgsList.getAdminUidArg());
      defaultArgs.remove(secureArgsList.getBindDnArg());
    }
    else
    {
      defaultArgs.add(secureArgsList.adminUidArg);
      defaultArgs.add(secureArgsList.getAdminUidArg());
    }
    defaultArgs.remove(secureArgsList.hostNameArg);
    defaultArgs.remove(secureArgsList.portArg);
    defaultArgs.remove(secureArgsList.getHostNameArg());
    defaultArgs.remove(secureArgsList.getPortArg());
    referencedHostNameArg =
            StringArgument.builder(OPTION_LONG_REFERENCED_HOST_NAME)
                    .shortIdentifier(OPTION_SHORT_HOST)
@@ -314,7 +315,7 @@
   */
  public String getDefaultAdministratorUID()
  {
    return secureArgsList.adminUidArg.getDefaultValue();
    return secureArgsList.getAdminUidArg().getDefaultValue();
  }
  /**
opendj-server-legacy/src/main/java/org/opends/server/admin/client/cli/SecureConnectionCliArgs.java
@@ -68,42 +68,24 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /** The 'hostName' global argument. */
  public StringArgument hostNameArg;
  /** The 'port' global argument. */
  public IntegerArgument portArg;
  /** The 'bindDN' global argument. */
  public StringArgument bindDnArg;
  /** The 'adminUID' global argument. */
  public StringArgument adminUidArg;
  /** The 'bindPasswordFile' global argument. */
  public FileBasedArgument bindPasswordFileArg;
  /** The 'bindPassword' global argument. */
  public StringArgument bindPasswordArg;
  /** The 'trustAllArg' global argument. */
  public BooleanArgument trustAllArg;
  /** The 'trustStore' global argument. */
  public StringArgument trustStorePathArg;
  /** The 'trustStorePassword' global argument. */
  public StringArgument trustStorePasswordArg;
  /** The 'trustStorePasswordFile' global argument. */
  public FileBasedArgument trustStorePasswordFileArg;
  /** The 'keyStore' global argument. */
  public StringArgument keyStorePathArg;
  /** The 'keyStorePassword' global argument. */
  public StringArgument keyStorePasswordArg;
  /** The 'keyStorePasswordFile' global argument. */
  public FileBasedArgument keyStorePasswordFileArg;
  /** The 'certNicknameArg' global argument. */
  public StringArgument certNicknameArg;
  /** The 'useSSLArg' global argument. */
  public BooleanArgument useSSLArg;
  /** The 'useStartTLSArg' global argument. */
  public BooleanArgument useStartTLSArg;
  /** Argument indicating a SASL option. */
  public StringArgument saslOptionArg;
  /** Argument to specify the connection timeout. */
  public IntegerArgument connectTimeoutArg;
  private StringArgument hostNameArg;
  private IntegerArgument portArg;
  private StringArgument bindDnArg;
  private StringArgument adminUidArg;
  private FileBasedArgument bindPasswordFileArg;
  private StringArgument bindPasswordArg;
  private BooleanArgument trustAllArg;
  private StringArgument trustStorePathArg;
  private StringArgument trustStorePasswordArg;
  private FileBasedArgument trustStorePasswordFileArg;
  private StringArgument keyStorePathArg;
  private StringArgument keyStorePasswordArg;
  private FileBasedArgument keyStorePasswordFileArg;
  private StringArgument certNicknameArg;
  private BooleanArgument useSSLArg;
  private BooleanArgument useStartTLSArg;
  private StringArgument saslOptionArg;
  private IntegerArgument connectTimeoutArg;
  /** Private container for global arguments. */
  private Set<Argument> argList;
@@ -165,18 +147,6 @@
  }
  /**
   * Tells whether this parser uses the Administrator UID (instead of the bind
   * DN) or not.
   *
   * @return {@code true} if this parser uses the Administrator UID and
   *         {@code false} otherwise.
   */
  public boolean useAdminUID()
  {
    return !adminUidArg.isHidden();
  }
  /**
   * Get the bindDN which has to be used for the command.
   *
   * @return The bindDN specified by the command line argument, or the default
@@ -229,7 +199,7 @@
    bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN);
    argList.add(bindDnArg);
    // Classes that required admin UID to be not hidden must use CommonsArguments.adminUid().
    // Classes that required admin UID to be not hidden must call createVisibleAdminUidArgument(localizedDescription)
    adminUidArg = adminUidHiddenArgument(INFO_DESCRIPTION_ADMIN_UID.get());
    bindPasswordArg = bindPasswordArgument();
@@ -376,26 +346,6 @@
  }
  /**
   * Indicate if the SSL mode is required.
   *
   * @return True if SSL mode is required
   */
  public boolean useSSL()
  {
    return useSSLArg.isPresent() || alwaysSSL();
  }
  /**
   * Indicate if the startTLS mode is required.
   *
   * @return True if startTLS mode is required
   */
  public boolean useStartTLS()
  {
    return useStartTLSArg.isPresent();
  }
  /**
   * Indicate if the SSL mode is always used.
   *
   * @return True if SSL mode is always used.
@@ -658,9 +608,9 @@
    {
      this.adminUidArg = adminUid(description);
    }
    catch (ArgumentException e)
    catch (final ArgumentException unexpected)
    {
      // Will never append.
      throw new RuntimeException("Unexpected");
    }
  }
@@ -669,4 +619,207 @@
    return portArgument(
            defaultValue, alwaysSSL ? INFO_DESCRIPTION_ADMIN_PORT.get() : INFO_DESCRIPTION_PORT.get());
  }
  /**
   * Return the 'keyStore' global argument.
   *
   * @return The 'keyStore' global argument.
   */
  public StringArgument getKeyStorePathArg() {
    return keyStorePathArg;
  }
  /**
   * Return the 'hostName' global argument.
   *
   * @return The 'hostName' global argument.
   */
  public StringArgument getHostNameArg() {
    return hostNameArg;
  }
  /**
   * Return the 'port' global argument.
   *
   * @return The 'port' global argument.
   */
  public IntegerArgument getPortArg() {
    return portArg;
  }
  /**
   * Return the 'bindDN' global argument.
   *
   * @return The 'bindDN' global argument.
   */
  public StringArgument getBindDnArg() {
    return bindDnArg;
  }
  /**
   * Return the 'adminUID' global argument.
   *
   * @return The 'adminUID' global argument.
   */
  public StringArgument getAdminUidArg() {
    return adminUidArg;
  }
  /**
   * Return the 'bindPasswordFile' global argument.
   *
   * @return The 'bindPasswordFile' global argument.
   */
  public FileBasedArgument getBindPasswordFileArg() {
    return bindPasswordFileArg;
  }
  /**
   * Return the 'bindPassword' global argument.
   *
   * @return The 'bindPassword' global argument.
   */
  public StringArgument getBindPasswordArg() {
    return bindPasswordArg;
  }
  /**
   * Return the 'trustAllArg' global argument.
   *
   * @return The 'trustAllArg' global argument.
   */
  public BooleanArgument getTrustAllArg() {
    return trustAllArg;
  }
  /**
   * Return the 'trustStore' global argument.
   *
   * @return The 'trustStore' global argument.
   */
  public StringArgument getTrustStorePathArg() {
    return trustStorePathArg;
  }
  /**
   * Return the 'trustStorePassword' global argument.
   *
   * @return The 'trustStorePassword' global argument.
   */
  public StringArgument getTrustStorePasswordArg() {
    return trustStorePasswordArg;
  }
  /**
   * Return the 'trustStorePasswordFile' global argument.
   *
   * @return The 'trustStorePasswordFile' global argument.
   */
  public FileBasedArgument getTrustStorePasswordFileArg() {
    return trustStorePasswordFileArg;
  }
  /**
   * Return the 'keyStorePassword' global argument.
   *
   * @return The 'keyStorePassword' global argument.
   */
  public StringArgument getKeyStorePasswordArg() {
    return keyStorePasswordArg;
  }
  /**
   * Return the 'keyStorePasswordFile' global argument.
   *
   * @return The 'keyStorePasswordFile' global argument.
   */
  public FileBasedArgument getKeyStorePasswordFileArg() {
    return keyStorePasswordFileArg;
  }
  /**
   * Return the 'certNicknameArg' global argument.
   *
   * @return The 'certNicknameArg' global argument.
   */
  public StringArgument getCertNicknameArg() {
    return certNicknameArg;
  }
  /**
   * Return the 'useSSLArg' global argument.
   *
   * @return The 'useSSLArg' global argument.
   */
  public BooleanArgument getUseSSLArg() {
    return useSSLArg;
  }
  /**
   * Return the 'useStartTLSArg' global argument.
   *
   * @return The 'useStartTLSArg' global argument.
   */
  public BooleanArgument getUseStartTLSArg() {
    return useStartTLSArg;
  }
  /**
   * Return the 'saslOption' argument.
   *
   * @return the 'saslOption' argument.
   */
  public StringArgument getSaslOptionArg() {
    return saslOptionArg;
  }
  /**
   * Return the 'connectTimeout' argument.
   *
   * @return the 'connectTimeout' argument.
   */
  public IntegerArgument getConnectTimeoutArg() {
    return connectTimeoutArg;
  }
  /**
   * Set the bind DN argument with the provided description.
   * Note that this method will create a new {@link Argument} instance replacing the current one.
   *
   * @param description
   *         The localized description which will be used in help messages.
   */
  public void setBindDnArgDescription(final LocalizableMessage description)
  {
    try
    {
      this.bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN, description);
    }
    catch (final ArgumentException unexpected)
    {
      throw new RuntimeException("unexpected");
    }
  }
  /**
   * Set the bind password argument.
   *
   * @param bindPasswordArg
   *         The argument which will replace the current one.
   */
  public void setBindPasswordArgument(final StringArgument bindPasswordArg)
  {
    this.bindPasswordArg = bindPasswordArg;
  }
  /**
   * Set the bind password file argument.
   *
   * @param bindPasswordFileArg
   *         The argument which will replace the current one.
   */
  public void setBindPasswordFileArgument(final FileBasedArgument bindPasswordFileArg)
  {
    this.bindPasswordFileArg = bindPasswordFileArg;
  }
}
opendj-server-legacy/src/main/java/org/opends/server/admin/client/cli/SecureConnectionCliParser.java
@@ -22,7 +22,6 @@
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.cli.CommonArguments.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Collection;
@@ -37,9 +36,6 @@
import com.forgerock.opendj.cli.ArgumentException;
import com.forgerock.opendj.cli.ArgumentGroup;
import com.forgerock.opendj.cli.BooleanArgument;
import com.forgerock.opendj.cli.ClientException;
import com.forgerock.opendj.cli.ConsoleApplication;
import com.forgerock.opendj.cli.FileBasedArgument;
import com.forgerock.opendj.cli.StringArgument;
import com.forgerock.opendj.cli.SubCommandArgumentParser;
@@ -53,18 +49,12 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /** The 'showUsage' global argument. */
  protected BooleanArgument showUsageArg;
  /** The 'verbose' global argument. */
  protected BooleanArgument verboseArg;
  /** The secure args list object. */
  protected SecureConnectionCliArgs secureArgsList;
  /** Argument indicating a properties file argument. */
  protected StringArgument propertiesFileArg;
  /** The argument which should be used to indicate that we will not look for properties file. */
  protected BooleanArgument noPropertiesFileArg;
@@ -99,7 +89,6 @@
    return secureArgsList.getBindDN();
  }
  /**
   * Returns the Administrator UID provided in the command-line.
   * @return the Administrator UID provided in the command-line.
@@ -110,86 +99,6 @@
  }
  /**
   * Get the password which has to be used for the command.
   *
   * @param dn
   *          The user DN for which to password could be asked.
   * @param out
   *          The input stream to used if we have to prompt to the
   *          user.
   * @param err
   *          The error stream to used if we have to prompt to the
   *          user.
   * @param pwdArg
   *          The password StringArgument argument.
   * @param fileArg
   *          The password FileBased argument.
   * @return The password stored into the specified file on by the
   *         command line argument, or prompts it if not specified.
   */
  protected String getBindPassword(String dn, OutputStream out,
      OutputStream err, StringArgument pwdArg, FileBasedArgument fileArg)
  {
    if (fileArg.isPresent())
    {
      return fileArg.getValue();
    }
    String bindPasswordValue = pwdArg.isPresent() ? pwdArg.getValue() : null;
    if (bindPasswordValue == null || "-".equals(bindPasswordValue))
    {
      // Read the password from the STDin.
      try
      {
        return readPassword(dn, out);
      }
      catch (Exception ex)
      {
        logger.traceException(ex);
        try
        {
          err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes());
          err.write(LINE_SEPARATOR.getBytes());
        }
        catch (IOException e)
        {
          // Nothing to do.
        }
      }
    }
    return bindPasswordValue;
  }
  private String readPassword(String dn, OutputStream out) throws IOException,
      ClientException
  {
    out.write(INFO_LDAPAUTH_PASSWORD_PROMPT.get(dn).toString().getBytes());
    out.flush();
    char[] pwChars = ConsoleApplication.readPassword();
    return new String(pwChars);
  }
  /**
   * Gets the password which has to be used for the command.
   *
   * @param dn
   *          The user DN for which to password could be asked.
   * @param out
   *          The input stream to used if we have to prompt to the
   *          user.
   * @param err
   *          The error stream to used if we have to prompt to the
   *          user.
   * @return The password stored into the specified file on by the
   *         command line argument, or prompts it if not specified.
   */
  public String getBindPassword(String dn, OutputStream out, OutputStream err)
  {
    return getBindPassword(dn, out, err, secureArgsList.bindPasswordArg,
        secureArgsList.bindPasswordFileArg);
  }
  /**
   * Gets the password which has to be used for the command without prompting
   * the user.  If no password was specified, return null.
   *
@@ -198,8 +107,7 @@
   */
  public String getBindPassword()
  {
    return getBindPassword(secureArgsList.bindPasswordArg,
        secureArgsList.bindPasswordFileArg);
    return getBindPassword(secureArgsList.getBindPasswordArg(), secureArgsList.getBindPasswordFileArg());
  }
  /**
@@ -220,7 +128,8 @@
    secureArgsList = new SecureConnectionCliArgs(alwaysSSL);
    Set<Argument> set = secureArgsList.createGlobalArguments();
    showUsageArg = showUsageArgument();
    /* The 'showUsage' global argument. */
    final BooleanArgument showUsageArg = showUsageArgument();
    setUsageArgument(showUsageArg, outStream);
    set.add(showUsageArg);
@@ -347,27 +256,6 @@
    return verboseArg.isPresent();
  }
  /**
   * Indicate if the SSL mode is required.
   *
   * @return True if SSL mode is required
   */
  public boolean useSSL()
  {
    return secureArgsList.useSSL();
  }
  /**
   * Indicate if the startTLS mode is required.
   *
   * @return True if startTLS mode is required
   */
  public boolean useStartTLS()
  {
    return secureArgsList.useStartTLS();
  }
  /**
   * Handle TrustStore.
   *
@@ -389,7 +277,7 @@
  {
    try
    {
      return secureArgsList.connectTimeoutArg.getIntValue();
      return secureArgsList.getConnectTimeoutArg().getIntValue();
    }
    catch (ArgumentException ae)
    {
opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java
@@ -287,11 +287,11 @@
    int returnValue;
    super.validateGlobalOptions(buf);
    ArrayList<LocalizableMessage> errors = new ArrayList<>();
    if (secureArgsList.bindPasswordArg.isPresent() &&
        secureArgsList.bindPasswordFileArg.isPresent()) {
    if (secureArgsList.getBindPasswordArg().isPresent() &&
        secureArgsList.getBindPasswordFileArg().isPresent()) {
      LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get(
          secureArgsList.bindPasswordArg.getLongIdentifier(),
          secureArgsList.bindPasswordFileArg.getLongIdentifier());
          secureArgsList.getBindPasswordArg().getLongIdentifier(),
          secureArgsList.getBindPasswordFileArg().getLongIdentifier());
      errors.add(message);
    }
@@ -338,8 +338,8 @@
          !isPurgeHistoricalSubcommand())
      {
        errors.add(ERR_REPLICATION_NO_ADMINISTRATOR_PASSWORD_PROVIDED.get(
            "--"+secureArgsList.bindPasswordArg.getLongIdentifier(),
            "--"+secureArgsList.bindPasswordFileArg.getLongIdentifier()));
            "--"+ secureArgsList.getBindPasswordArg().getLongIdentifier(),
            "--"+ secureArgsList.getBindPasswordFileArg().getLongIdentifier()));
      }
    }
@@ -392,11 +392,11 @@
    ArrayList<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL));
    Argument[] argsToRemove = {
      secureArgsList.hostNameArg,
      secureArgsList.portArg,
      secureArgsList.bindDnArg,
      secureArgsList.bindPasswordFileArg,
      secureArgsList.bindPasswordArg
            secureArgsList.getHostNameArg(),
            secureArgsList.getPortArg(),
            secureArgsList.getBindDnArg(),
            secureArgsList.getBindPasswordFileArg(),
            secureArgsList.getBindPasswordArg()
    };
    for (Argument arg : argsToRemove)
@@ -421,23 +421,23 @@
    secureArgsList.createVisibleAdminUidArgument(
        INFO_DESCRIPTION_REPLICATION_ADMIN_UID.get(ENABLE_REPLICATION_SUBCMD_NAME));
    defaultArgs.add(index++, secureArgsList.adminUidArg);
    defaultArgs.add(index++, secureArgsList.getAdminUidArg());
    secureArgsList.bindPasswordArg =
    secureArgsList.setBindPasswordArgument(
            StringArgument.builder(OPTION_LONG_ADMIN_PWD)
                    .shortIdentifier(OPTION_SHORT_BINDPWD)
                    .description(INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORD.get())
                    .valuePlaceholder(INFO_BINDPWD_PLACEHOLDER.get())
                    .buildArgument();
    defaultArgs.add(index++, secureArgsList.bindPasswordArg);
                    .buildArgument());
    defaultArgs.add(index++, secureArgsList.getBindPasswordArg());
    secureArgsList.bindPasswordFileArg =
    secureArgsList.setBindPasswordFileArgument(
            FileBasedArgument.builder(OPTION_LONG_ADMIN_PWD_FILE)
                    .shortIdentifier(OPTION_SHORT_BINDPWD_FILE)
                    .description(INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORDFILE.get())
                    .valuePlaceholder(INFO_BINDPWD_FILE_PLACEHOLDER.get())
                    .buildArgument();
    defaultArgs.add(index++, secureArgsList.bindPasswordFileArg);
                    .buildArgument());
    defaultArgs.add(index++, secureArgsList.getBindPasswordFileArg());
    defaultArgs.remove(verboseArg);
@@ -672,13 +672,7 @@
    disableReplicationSubCmd = new SubCommand(this,
        DISABLE_REPLICATION_SUBCMD_NAME,
        INFO_DESCRIPTION_SUBCMD_DISABLE_REPLICATION.get());
    secureArgsList.bindDnArg =
            StringArgument.builder(OPTION_LONG_BINDDN)
                    .shortIdentifier(OPTION_SHORT_BINDDN)
                    .description(INFO_DESCRIPTION_DISABLE_REPLICATION_BINDDN.get())
                    .defaultValue("cn=Directory Manager")
                    .valuePlaceholder(INFO_BINDDN_PLACEHOLDER.get())
                    .buildArgument();
    secureArgsList.setBindDnArgDescription(INFO_DESCRIPTION_DISABLE_REPLICATION_BINDDN.get());
    disableReplicationServerArg =
            BooleanArgument.builder("disableReplicationServer")
                    .shortIdentifier('a')
@@ -689,8 +683,8 @@
                    .description(INFO_DESCRIPTION_DISABLE_ALL.get())
                    .buildArgument();
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg, secureArgsList.bindDnArg,
    Argument[] argsToAdd = { secureArgsList.getHostNameArg(),
            secureArgsList.getPortArg(), secureArgsList.getBindDnArg(),
        disableReplicationServerArg, disableAllArg};
    for (Argument arg : argsToAdd)
    {
@@ -757,8 +751,8 @@
        INITIALIZE_ALL_REPLICATION_SUBCMD_NAME,
        INFO_DESCRIPTION_SUBCMD_INITIALIZE_ALL_REPLICATION.get(
            INITIALIZE_REPLICATION_SUBCMD_NAME));
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg };
    Argument[] argsToAdd = { secureArgsList.getHostNameArg(),
            secureArgsList.getPortArg() };
    for (Argument arg : argsToAdd)
    {
      initializeAllReplicationSubCmd.addArgument(arg);
@@ -786,8 +780,8 @@
                    .hidden()
                    .buildArgument();
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg,
    Argument[] argsToAdd = { secureArgsList.getHostNameArg(),
            secureArgsList.getPortArg(),
        externalInitializationLocalOnlyArg};
    for (Argument arg : argsToAdd)
@@ -810,8 +804,8 @@
        POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME,
        INFO_DESCRIPTION_SUBCMD_POST_EXTERNAL_INITIALIZATION.get(
            PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME));
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg };
    Argument[] argsToAdd = { secureArgsList.getHostNameArg(),
            secureArgsList.getPortArg() };
    for (Argument arg : argsToAdd)
    {
      postExternalInitializationSubCmd.addArgument(arg);
@@ -852,7 +846,7 @@
                    .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get())
                    .buildArgument();
    addArgumentsToSubCommand(
            statusReplicationSubCmd, secureArgsList.hostNameArg, secureArgsList.portArg, scriptFriendlyArg);
            statusReplicationSubCmd, secureArgsList.getHostNameArg(), secureArgsList.getPortArg(), scriptFriendlyArg);
  }
  /**
@@ -878,7 +872,7 @@
        INFO_DESCRIPTION_SUBCMD_PURGE_HISTORICAL.get());
    addArgumentsToSubCommand(purgeHistoricalSubCmd,
            secureArgsList.hostNameArg, secureArgsList.portArg, maximumDurationArg);
            secureArgsList.getHostNameArg(), secureArgsList.getPortArg(), maximumDurationArg);
    addArgumentsToSubCommand(purgeHistoricalSubCmd, taskArgs.getArguments());
  }
@@ -934,7 +928,7 @@
   */
  public String getBindPasswordAdmin()
  {
    return getBindPassword(secureArgsList.bindPasswordArg, secureArgsList.bindPasswordFileArg);
    return getBindPassword(secureArgsList.getBindPasswordArg(), secureArgsList.getBindPasswordFileArg());
  }
  /**
@@ -962,7 +956,7 @@
   */
  StringArgument getAdminUidArg()
  {
    return secureArgsList.adminUidArg;
    return secureArgsList.getAdminUidArg();
  }
  /**
@@ -1028,7 +1022,7 @@
   */
  public String getHostNameToDisable()
  {
    return getValue(secureArgsList.hostNameArg);
    return getValue(secureArgsList.getHostNameArg());
  }
  /**
@@ -1039,7 +1033,7 @@
   */
  public String getHostNameToDisableOrDefault()
  {
    return getValueOrDefault(secureArgsList.hostNameArg);
    return getValueOrDefault(secureArgsList.getHostNameArg());
  }
  /**
@@ -1050,7 +1044,7 @@
   */
  public String getBindDNToDisable()
  {
    return getValue(secureArgsList.bindDnArg);
    return getValue(secureArgsList.getBindDnArg());
  }
  /**
@@ -1059,7 +1053,7 @@
   */
  public String getHostNameToStatusOrDefault()
  {
    return getValueOrDefault(secureArgsList.hostNameArg);
    return getValueOrDefault(secureArgsList.getHostNameArg());
  }
  /**
@@ -1070,7 +1064,7 @@
   */
  public String getHostNameToInitializeAllOrDefault()
  {
    return getValueOrDefault(secureArgsList.hostNameArg);
    return getValueOrDefault(secureArgsList.getHostNameArg());
  }
  /**
@@ -1169,7 +1163,7 @@
   */
  public int getPortToDisable()
  {
    return getValue(secureArgsList.portArg);
    return getValue(secureArgsList.getPortArg());
  }
  /**
@@ -1180,7 +1174,7 @@
   */
  public int getPortToDisableOrDefault()
  {
    return getValueOrDefault(secureArgsList.portArg);
    return getValueOrDefault(secureArgsList.getPortArg());
  }
  /**
@@ -1191,7 +1185,7 @@
   */
  public int getPortToInitializeAllOrDefault()
  {
    return getValueOrDefault(secureArgsList.portArg);
    return getValueOrDefault(secureArgsList.getPortArg());
  }
  /**
@@ -1200,7 +1194,7 @@
   */
  public int getPortToStatusOrDefault()
  {
    return getValueOrDefault(secureArgsList.portArg);
    return getValueOrDefault(secureArgsList.getPortArg());
  }
  /**
@@ -1556,7 +1550,7 @@
  {
    Argument[][] conflictingPairs =
    {
        {getAdminUidArg(), secureArgsList.bindDnArg},
        {getAdminUidArg(), secureArgsList.getBindDnArg() },
        {disableAllArg, disableReplicationServerArg},
        {disableAllArg, baseDNsArg}
    };
@@ -1665,8 +1659,8 @@
      // This have to be explicitly specified because their original definition
      // has been replaced.
      boolean adminArgsPresent = getAdminUidArg().isPresent() ||
      secureArgsList.bindPasswordArg.isPresent() ||
      secureArgsList.bindPasswordFileArg.isPresent();
      secureArgsList.getBindPasswordArg().isPresent() ||
      secureArgsList.getBindPasswordFileArg().isPresent();
      return secureArgsPresent || adminArgsPresent;
    }
    return true;
opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java
@@ -448,7 +448,7 @@
      }
    }
    if (argParser.getSecureArgsList().bindPasswordFileArg.isPresent())
    if (argParser.getSecureArgsList().getBindPasswordFileArg().isPresent())
    {
      try
      {
@@ -458,7 +458,7 @@
                .valuePlaceholder(INFO_BINDPWD_FILE_PLACEHOLDER.get())
                .buildArgument();
        userProvidedAdminPwdFile.getNameToValueMap().putAll(
            argParser.getSecureArgsList().bindPasswordFileArg.getNameToValueMap());
            argParser.getSecureArgsList().getBindPasswordFileArg().getNameToValueMap());
      }
      catch (Throwable t)
      {
@@ -2150,9 +2150,9 @@
    else if (bindDn1 == null)
    {
      pwd = adminPwd;
      if (argParser.getSecureArgsList().bindPasswordFileArg.isPresent())
      if (argParser.getSecureArgsList().getBindPasswordFileArg().isPresent())
      {
        pwdFile = argParser.getSecureArgsList().bindPasswordFileArg.
        pwdFile = argParser.getSecureArgsList().getBindPasswordFileArg().
          getNameToValueMap();
      }
    }
@@ -2352,7 +2352,7 @@
    uData.getServer1().setSecureReplication(secureReplication1);
    uData.getServer1().setConfigureReplicationServer(configureReplicationServer1);
    uData.getServer1().setConfigureReplicationDomain(configureReplicationDomain1);
    firstServerCommandBuilder = new CommandBuilder(null, null);
    firstServerCommandBuilder = new CommandBuilder();
    if (mustPrintCommandBuilder())
    {
      firstServerCommandBuilder.append(sourceServerCI.getCommandBuilder());
@@ -2390,9 +2390,9 @@
      {
        doNotDisplayFirstError = true;
        pwd = adminPwd;
        if (argParser.getSecureArgsList().bindPasswordFileArg.isPresent())
        if (argParser.getSecureArgsList().getBindPasswordFileArg().isPresent())
        {
          pwdFile = argParser.getSecureArgsList().bindPasswordFileArg.
          pwdFile = argParser.getSecureArgsList().getBindPasswordFileArg().
            getNameToValueMap();
        }
      }
@@ -3138,9 +3138,9 @@
    int portSource = argParser.getPortSource();
    Map<String, String> pwdFile = null;
    if (argParser.getSecureArgsList().bindPasswordFileArg.isPresent())
    if (argParser.getSecureArgsList().getBindPasswordFileArg().isPresent())
    {
      pwdFile = argParser.getSecureArgsList().bindPasswordFileArg.getNameToValueMap();
      pwdFile = argParser.getSecureArgsList().getBindPasswordFileArg().getNameToValueMap();
    }
    /*
@@ -3193,7 +3193,7 @@
      uData.setAdminPwd(adminPwd);
    }
    firstServerCommandBuilder = new CommandBuilder(null, null);
    firstServerCommandBuilder = new CommandBuilder();
    if (mustPrintCommandBuilder())
    {
      firstServerCommandBuilder.append(sourceServerCI.getCommandBuilder());
opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java
@@ -278,10 +278,10 @@
      {
        logger.error(LocalizableMessage.raw("Error parsing url: " + ldapUrl));
      }
      secureArgsList.hostNameArg.setPresent(true);
      secureArgsList.portArg.setPresent(true);
      secureArgsList.hostNameArg.addValue(secureArgsList.hostNameArg.getDefaultValue());
      secureArgsList.portArg.addValue(Integer.toString(port));
      secureArgsList.getHostNameArg().setPresent(true);
      secureArgsList.getPortArg().setPresent(true);
      secureArgsList.getHostNameArg().addValue(secureArgsList.getHostNameArg().getDefaultValue());
      secureArgsList.getPortArg().addValue(Integer.toString(port));
      // We already know if SSL or StartTLS can be used.  If we cannot
      // use them we will not propose them in the connection parameters
      // and if none of them can be used we will just not ask for the
opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCliArgumentParser.java
@@ -78,8 +78,8 @@
  throws ArgumentException
  {
    ArrayList<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL));
    defaultArgs.remove(secureArgsList.portArg);
    defaultArgs.remove(secureArgsList.hostNameArg);
    defaultArgs.remove(secureArgsList.getPortArg());
    defaultArgs.remove(secureArgsList.getHostNameArg());
    defaultArgs.remove(verboseArg);
    defaultArgs.remove(noPropertiesFileArg);
    defaultArgs.remove(propertiesFileArg);
@@ -174,9 +174,9 @@
   */
  public String getExplicitBindDn()
  {
    if (secureArgsList.bindDnArg.isPresent())
    if (secureArgsList.getBindDnArg().isPresent())
    {
      return secureArgsList.bindDnArg.getValue();
      return secureArgsList.getBindDnArg().getValue();
    }
    return null;
  }
@@ -187,6 +187,6 @@
   */
  public String getDefaultBindDn()
  {
    return secureArgsList.bindDnArg.getDefaultValue();
    return secureArgsList.getBindDnArg().getDefaultValue();
  }
}
opendj-server-legacy/src/main/java/org/opends/server/util/args/LDAPConnectionArgumentParser.java
@@ -12,7 +12,7 @@
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008-2010 Sun Microsystems, Inc.
 * Portions Copyright 2011-2015 ForgeRock AS.
 * Portions Copyright 2011-2016 ForgeRock AS.
 */
package org.opends.server.util.args;
@@ -139,29 +139,11 @@
  private LDAPConnection connect(SecureConnectionCliArgs args, PrintStream out, PrintStream err)
      throws LDAPConnectionException, ArgumentException
  {
    // If both a bind password and bind password file were provided, then return
    // an error.
    if (args.bindPasswordArg.isPresent() && args.bindPasswordFileArg.isPresent())
    {
      printAndThrowException(err, ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
          args.bindPasswordArg.getLongIdentifier(), args.bindPasswordFileArg.getLongIdentifier()));
    }
    // If both a key store password and key store password file were provided,
    // then return an error.
    if (args.keyStorePasswordArg.isPresent() && args.keyStorePasswordFileArg.isPresent())
    {
      printAndThrowException(err, ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
          args.keyStorePasswordArg.getLongIdentifier(), args.keyStorePasswordFileArg.getLongIdentifier()));
    }
    // If both a trust store password and trust store password file were
    // provided, then return an error.
    if (args.trustStorePasswordArg.isPresent() && args.trustStorePasswordFileArg.isPresent())
    {
      printAndThrowException(err, ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
          args.trustStorePasswordArg.getLongIdentifier(), args.trustStorePasswordFileArg.getLongIdentifier()));
    }
    // Checks for conflicting arguments
    throwIfArgumentsConflict(err, args.getBindPasswordArg(), args.getBindPasswordArg());
    throwIfArgumentsConflict(err, args.getKeyStorePasswordArg(), args.getKeyStorePasswordFileArg());
    throwIfArgumentsConflict(err, args.getTrustStorePasswordArg(), args.getTrustStorePasswordFileArg());
    throwIfArgumentsConflict(err, args.getUseSSLArg(), args.getUseStartTLSArg());
    // Create the LDAP connection options object, which will be used to
    // customize the way that we connect to the server and specify a set of
@@ -171,30 +153,25 @@
    // See if we should use SSL or StartTLS when establishing the connection.
    // If so, then make sure only one of them was specified.
    if (args.useSSLArg.isPresent())
    if (args.getUseSSLArg().isPresent())
    {
      if (args.useStartTLSArg.isPresent())
      {
        printAndThrowException(err, ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
            args.useSSLArg.getLongIdentifier(), args.useSSLArg.getLongIdentifier()));
      }
      connectionOptions.setUseSSL(true);
    }
    else if (args.useStartTLSArg.isPresent())
    else if (args.getUseStartTLSArg().isPresent())
    {
      connectionOptions.setStartTLS(true);
    }
    // If we should blindly trust any certificate, then install the appropriate
    // SSL connection factory.
    if (args.useSSLArg.isPresent() || args.useStartTLSArg.isPresent())
    if (args.getUseSSLArg().isPresent() || args.getUseStartTLSArg().isPresent())
    {
      try
      {
        String clientAlias;
        if (args.certNicknameArg.isPresent())
        if (args.getCertNicknameArg().isPresent())
        {
          clientAlias = args.certNicknameArg.getValue();
          clientAlias = args.getCertNicknameArg().getValue();
        }
        else
        {
@@ -202,12 +179,12 @@
        }
        SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory();
        sslConnectionFactory.init(args.trustAllArg.isPresent(),
                                  args.keyStorePathArg.getValue(),
                                  args.keyStorePasswordArg.getValue(),
        sslConnectionFactory.init(args.getTrustAllArg().isPresent(),
                                  args.getKeyStorePathArg().getValue(),
                                  args.getKeyStorePasswordArg().getValue(),
                                  clientAlias,
                                  args.trustStorePathArg.getValue(),
                                  args.trustStorePasswordArg.getValue());
                                  args.getTrustStorePathArg().getValue(),
                                  args.getTrustStorePasswordArg().getValue());
        connectionOptions.setSSLConnectionFactory(sslConnectionFactory);
      }
      catch (SSLConnectionException sce)
@@ -218,12 +195,12 @@
    // If one or more SASL options were provided, then make sure that one of
    // them was "mech" and specified a valid SASL mechanism.
    if (args.saslOptionArg.isPresent())
    if (args.getSaslOptionArg().isPresent())
    {
      String mechanism = null;
      LinkedList<String> options = new LinkedList<>();
      for (String s : args.saslOptionArg.getValues())
      for (String s : args.getSaslOptionArg().getValues())
      {
        int equalPos = s.indexOf('=');
        if (equalPos <= 0)
@@ -256,14 +233,14 @@
      }
    }
    int timeout = args.connectTimeoutArg.getIntValue();
    int timeout = args.getConnectTimeoutArg().getIntValue();
    final String passwordValue = getPasswordValue(
        args.bindPasswordArg, args.bindPasswordFileArg, args.bindDnArg, out, err);
            args.getBindPasswordArg(), args.getBindPasswordFileArg(), args.getBindDnArg(), out, err);
    return connect(
            args.hostNameArg.getValue(),
            args.portArg.getIntValue(),
            args.bindDnArg.getValue(),
            args.getHostNameArg().getValue(),
            args.getPortArg().getIntValue(),
            args.getBindDnArg().getValue(),
            passwordValue,
            connectionOptions, timeout, out, err);
  }
@@ -486,4 +463,13 @@
      ae.printStackTrace(); // Should never happen
    }
  }
  private void throwIfArgumentsConflict(final PrintStream err, final Argument arg1, final Argument arg2)
      throws ArgumentException
  {
    if (arg1.isPresent() && arg2.isPresent())
    {
      printAndThrowException(err, ERR_TOOL_CONFLICTING_ARGS.get(arg1.getLongIdentifier(), arg2.getLongIdentifier()));
    }
  }
}
opendj-server-legacy/src/main/java/org/opends/server/util/cli/LDAPConnectionConsoleInteraction.java
@@ -16,25 +16,31 @@
 */
package org.opends.server.util.cli;
import static com.forgerock.opendj.cli.Utils.portValidationCallback;
import static com.forgerock.opendj.cli.Utils.isDN;
import static com.forgerock.opendj.cli.Utils.getAdministratorDN;
import static com.forgerock.opendj.cli.Utils.getThrowableMsg;
import static org.opends.messages.ToolMessages.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.net.ssl.KeyManager;
import com.forgerock.opendj.cli.Argument;
import com.forgerock.opendj.cli.FileBasedArgument;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.opends.admin.ads.util.ApplicationKeyManager;
@@ -65,6 +71,13 @@
public class LDAPConnectionConsoleInteraction
{
  private static final Protocol DEFAULT_PROMPT_PROTOCOL = Protocol.SSL;
  private static final TrustMethod DEFAULT_PROMPT_TRUST_METHOD = TrustMethod.DISPLAY_CERTIFICATE;
  private static final TrustOption DEFAULT_PROMPT_TRUST_OPTION = TrustOption.SESSION;
  private static final boolean ALLOW_EMPTY_PATH = true;
  private static final boolean FILE_MUST_EXISTS = true;
  /**
   * Information from the latest console interaction.
   * TODO: should it extend MonoServerReplicationUserData or a subclass?
@@ -97,71 +110,61 @@
    private String truststorePassword;
    private KeyManager keyManager;
    private String keystorePath;
    private String keyStorePath;
    private String keystorePassword;
    private String certifNickname;
    private State(SecureConnectionCliArgs secureArgs)
    {
      useSSL = secureArgs.useSSL();
      useStartTLS = secureArgs.useStartTLS();
      trustAll = secureArgs.trustAllArg.isPresent();
      setSsl(secureArgs);
      trustAll = secureArgs.getTrustAllArg().isPresent();
    }
    /**
     * @return
     */
    protected LocalizableMessage getPrompt()
    {
      LocalizableMessage prompt;
      if (providedAdminUID != null)
      {
        prompt = INFO_LDAPAUTH_PASSWORD_PROMPT.get(providedAdminUID);
        return INFO_LDAPAUTH_PASSWORD_PROMPT.get(providedAdminUID);
      }
      else if (providedBindDN != null)
      {
        prompt = INFO_LDAPAUTH_PASSWORD_PROMPT.get(providedBindDN);
        return INFO_LDAPAUTH_PASSWORD_PROMPT.get(providedBindDN);
      }
      else if (bindDN != null)
      {
        prompt = INFO_LDAPAUTH_PASSWORD_PROMPT.get(bindDN);
        return INFO_LDAPAUTH_PASSWORD_PROMPT.get(bindDN);
      }
      else
      {
        prompt = INFO_LDAPAUTH_PASSWORD_PROMPT.get(adminUID);
      }
      return prompt;
      return INFO_LDAPAUTH_PASSWORD_PROMPT.get(adminUID);
    }
    /**
     * @return
     */
    protected String getAdminOrBindDN()
    {
      String dn;
      if (providedBindDN != null)
      {
        dn = providedBindDN;
        return providedBindDN;
      }
      else if (providedAdminUID != null)
      {
        dn = getAdministratorDN(providedAdminUID);
        return getAdministratorDN(providedAdminUID);
      }
      else if (bindDN != null)
      {
        dn = bindDN;
        return bindDN;
      }
      else if (adminUID != null)
      {
        dn = getAdministratorDN(adminUID);
        return getAdministratorDN(adminUID);
      }
      else
      {
        dn = null;
      }
      return dn;
      return null;
    }
    private void setSsl(final SecureConnectionCliArgs secureArgs)
    {
      this.useSSL = secureArgs.alwaysSSL() || secureArgs.getUseSSLArg().isPresent();
      this.useStartTLS = secureArgs.getUseStartTLSArg().isPresent();
    }
  }
  /** The console application. */
@@ -170,7 +173,7 @@
  private State state;
  /** The SecureConnectionCliArgsList object. */
  private SecureConnectionCliArgs secureArgsList;
  private final SecureConnectionCliArgs secureArgsList;
  /** The command builder that we can return with the connection information. */
  private CommandBuilder commandBuilder;
@@ -192,147 +195,87 @@
  private boolean useAdminOrBindDn;
  /** Enumeration description protocols for interactive CLI choices. */
  private enum Protocols
  private enum Protocol
  {
    LDAP(1, INFO_LDAP_CONN_PROMPT_SECURITY_LDAP.get()),
    SSL(2,  INFO_LDAP_CONN_PROMPT_SECURITY_USE_SSL.get()),
    START_TLS(3, INFO_LDAP_CONN_PROMPT_SECURITY_USE_START_TLS.get());
    LDAP(INFO_LDAP_CONN_PROMPT_SECURITY_LDAP.get()),
    SSL(INFO_LDAP_CONN_PROMPT_SECURITY_USE_SSL.get()),
    START_TLS(INFO_LDAP_CONN_PROMPT_SECURITY_USE_START_TLS.get());
    private Integer choice;
    private final LocalizableMessage message;
    private LocalizableMessage msg;
    /**
     * Private constructor.
     *
     * @param i
     *          the menu return value.
     * @param msg
     *          the message message.
     */
    private Protocols(int i, LocalizableMessage msg)
    Protocol(final LocalizableMessage message)
    {
      choice = i;
      this.msg = msg;
      this.message = message;
    }
    /**
     * Returns the choice number.
     *
     * @return the attribute name.
     */
    public Integer getChoice()
    private int getChoice()
    {
      return choice;
    }
    /**
     * Return the menu message.
     *
     * @return the menu message.
     */
    public LocalizableMessage getMenuMessage()
    {
      return msg;
      return ordinal() + 1;
    }
  }
  /**
   * Enumeration description protocols for interactive CLI choices.
   */
  /** Enumeration description protocols for interactive CLI choices. */
  private enum TrustMethod
  {
    TRUSTALL(1, INFO_LDAP_CONN_PROMPT_SECURITY_USE_TRUST_ALL.get()),
    TRUSTALL(INFO_LDAP_CONN_PROMPT_SECURITY_USE_TRUST_ALL.get()),
    TRUSTSTORE(INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE.get()),
    DISPLAY_CERTIFICATE(INFO_LDAP_CONN_PROMPT_SECURITY_MANUAL_CHECK.get());
    TRUSTSTORE(2, INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE.get()),
    private LocalizableMessage message;
    DISPLAY_CERTIFICATE(3, INFO_LDAP_CONN_PROMPT_SECURITY_MANUAL_CHECK.get());
    private Integer choice;
    private LocalizableMessage msg;
    /**
     * Private constructor.
     *
     * @param i
     *          the menu return value.
     * @param msg
     *          the message message.
     */
    private TrustMethod(int i, LocalizableMessage msg)
    TrustMethod(final LocalizableMessage message)
    {
      choice = Integer.valueOf(i);
      this.msg = msg;
      this.message = message;
    }
    /**
     * Returns the choice number.
     *
     * @return the attribute name.
     */
    public Integer getChoice()
    private int getChoice()
    {
      return choice;
      return ordinal() + 1;
    }
    /**
     * Return the menu message.
     *
     * @return the menu message.
     */
    public LocalizableMessage getMenuMessage()
    private static TrustMethod getTrustMethodForIndex(final int value)
    {
      return msg;
      for (final TrustMethod trustMethod : TrustMethod.values())
      {
        if (trustMethod.getChoice() == value)
        {
          return trustMethod;
        }
      }
      return null;
    }
  }
  /**
   * Enumeration description server certificate trust option.
   */
  /** Enumeration description server certificate trust option. */
  private enum TrustOption
  {
    UNTRUSTED(1, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_NO.get()),
    SESSION(2, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_SESSION.get()),
    PERMAMENT(3, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_ALWAYS.get()),
    CERTIFICATE_DETAILS(4, INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_DETAILS.get());
    UNTRUSTED(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_NO.get()),
    SESSION(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_SESSION.get()),
    PERMAMENT(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_ALWAYS.get()),
    CERTIFICATE_DETAILS(INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_DETAILS.get());
    private Integer choice;
    private LocalizableMessage message;
    private LocalizableMessage msg;
    /**
     * Private constructor.
     *
     * @param i
     *          the menu return value.
     * @param msg
     *          the message message.
     */
    private TrustOption(int i, LocalizableMessage msg)
    TrustOption(final LocalizableMessage message)
    {
      choice = Integer.valueOf(i);
      this.msg = msg;
      this.message = message;
    }
    /**
     * Returns the choice number.
     *
     * @return the attribute name.
     */
    public Integer getChoice()
    private int getChoice()
    {
      return choice;
      return ordinal() + 1;
    }
    /**
     * Return the menu message.
     *
     * @return the menu message.
     */
    public LocalizableMessage getMenuMessage()
    private static TrustOption getTrustOptionForIndex(final int value)
    {
      return msg;
      for (final TrustOption trustOption : TrustOption.values())
      {
        if (trustOption.getChoice() == value)
        {
          return trustOption;
        }
      }
      return null;
    }
  }
@@ -349,7 +292,7 @@
  {
    this.app = app;
    this.secureArgsList = secureArgs;
    this.commandBuilder = new CommandBuilder(null, null);
    this.commandBuilder = new CommandBuilder();
    state = new State(secureArgs);
    copySecureArgsList = new SecureConnectionCliArgs(secureArgs.alwaysSSL());
    try
@@ -387,447 +330,328 @@
   */
  public void run(boolean canUseStartTLS) throws ArgumentException
  {
    // Reset everything
    resetBeforeRun();
    resolveHostName();
    resolveConnectionType(canUseStartTLS);
    resolvePortNumber();
    resolveTrustAndKeyManagers();
    resolveCredentialLogin();
    resolveCredentialPassword();
    resolveConnectTimeout();
  }
  private void resetBeforeRun() throws ArgumentException
  {
    commandBuilder.clearArguments();
    copySecureArgsList.createGlobalArguments();
    state.providedAdminUID = null;
    state.providedBindDN = null;
  }
    boolean secureConnection = true;
  private void resolveHostName() throws ArgumentException
  {
    state.hostName = secureArgsList.getHostNameArg().getValue();
    promptForHostNameIfRequired();
    addArgToCommandBuilder(copySecureArgsList.getHostNameArg(), state.hostName);
  }
    // Get the LDAP host.
    state.hostName = secureArgsList.hostNameArg.getValue();
    final String tmpHostName = state.hostName;
    if (app.isInteractive() && !secureArgsList.hostNameArg.isPresent())
    {
      checkHeadingDisplayed();
  private void resolveConnectionType(boolean canUseStartTLS)
  {
    state.setSsl(secureArgsList);
    promptForConnectionTypeIfRequired(canUseStartTLS);
    addConnectionTypeToCommandBuilder();
  }
      ValidationCallback<String> callback = new ValidationCallback<String>()
      {
  private void resolvePortNumber() throws ArgumentException
  {
    portNumber = (state.useSSL && !secureArgsList.getPortArg().isPresent())
        ? secureArgsList.getPortFromConfig()
        : secureArgsList.getPortArg().getIntValue();
    promptForPortNumberIfRequired();
    addArgToCommandBuilder(copySecureArgsList.getPortArg(), String.valueOf(portNumber));
  }
        @Override
        public String validate(ConsoleApplication app, String input)
            throws ClientException
        {
          String ninput = input.trim();
          if (ninput.length() == 0)
          {
            return tmpHostName;
          }
          else
          {
            try
            {
              InetAddress.getByName(ninput);
              return ninput;
            }
            catch (UnknownHostException e)
            {
              // Try again...
              app.println();
              app.println(ERR_LDAP_CONN_BAD_HOST_NAME.get(ninput));
              app.println();
              return null;
            }
          }
        }
      };
      try
      {
        app.println();
        state.hostName = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_HOST_NAME.get(state.hostName), callback);
      }
      catch (ClientException e)
      {
        throw cannotReadConnectionParameters(e);
      }
    }
    copySecureArgsList.hostNameArg.clearValues();
    copySecureArgsList.hostNameArg.addValue(state.hostName);
    commandBuilder.addArgument(copySecureArgsList.hostNameArg);
    // Connection type
    state.useSSL = secureArgsList.useSSL();
    state.useStartTLS = secureArgsList.useStartTLS();
    boolean connectionTypeIsSet =
        secureArgsList.alwaysSSL()
            || secureArgsList.useSSLArg.isPresent()
            || secureArgsList.useStartTLSArg.isPresent()
            || (secureArgsList.useSSLArg.isValueSetByProperty() && secureArgsList.useStartTLSArg
                .isValueSetByProperty());
    if (app.isInteractive() && !connectionTypeIsSet)
    {
      checkHeadingDisplayed();
      MenuBuilder<Integer> builder = new MenuBuilder<>(app);
      builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_USE_SECURE_CTX.get());
      Protocols defaultProtocol;
      if (secureConnection)
      {
        defaultProtocol = Protocols.SSL;
      }
      else
      {
        defaultProtocol = Protocols.LDAP;
      }
      for (Protocols p : Protocols.values())
      {
        if (secureConnection && p.equals(Protocols.LDAP) && !displayLdapIfSecureParameters)
        {
          continue;
        }
        if (!canUseStartTLS && p.equals(Protocols.START_TLS))
        {
          continue;
        }
        int i =
            builder.addNumberedOption(p.getMenuMessage(), MenuResult.success(p
                .getChoice()));
        if (p.equals(defaultProtocol))
        {
          builder.setDefault(
              INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE.get(i),
              MenuResult.success(p.getChoice()));
        }
      }
      Menu<Integer> menu = builder.toMenu();
      try
      {
        MenuResult<Integer> result = menu.run();
        if (result.isSuccess())
        {
          if (result.getValue().equals(Protocols.SSL.getChoice()))
          {
            state.useSSL = true;
          }
          else if (result.getValue().equals(Protocols.START_TLS.getChoice()))
          {
            state.useStartTLS = true;
          }
        }
        else
        {
          // Should never happen.
          throw new RuntimeException();
        }
      }
      catch (ClientException e)
      {
        throw new RuntimeException(e);
      }
    }
    if (state.useSSL)
    {
      commandBuilder.addArgument(copySecureArgsList.useSSLArg);
    }
    else if (state.useStartTLS)
    {
      commandBuilder.addArgument(copySecureArgsList.useStartTLSArg);
    }
    // Get the LDAP port.
    if (!state.useSSL)
    {
      portNumber = secureArgsList.portArg.getIntValue();
    }
    else
    {
      if (secureArgsList.portArg.isPresent())
      {
        portNumber = secureArgsList.portArg.getIntValue();
      }
      else
      {
        portNumber = secureArgsList.getPortFromConfig();
      }
    }
    final int tmpPortNumber = portNumber;
    if (app.isInteractive() && !secureArgsList.portArg.isPresent())
    {
      checkHeadingDisplayed();
      ValidationCallback<Integer> callback = new ValidationCallback<Integer>()
      {
        @Override
        public Integer validate(ConsoleApplication app, String input)
            throws ClientException
        {
          String ninput = input.trim();
          if (ninput.length() == 0)
          {
            return tmpPortNumber;
          }
          else
          {
            try
            {
              int i = Integer.parseInt(ninput);
              if (i < 1 || i > 65535)
              {
                throw new NumberFormatException();
              }
              return i;
            }
            catch (NumberFormatException e)
            {
              // Try again...
              app.println();
              app.println(ERR_LDAP_CONN_BAD_PORT_NUMBER.get(ninput));
              app.println();
              return null;
            }
          }
        }
      };
      try
      {
        app.println();
        LocalizableMessage askPortNumber = null;
        if (secureArgsList.alwaysSSL())
        {
          askPortNumber = INFO_ADMIN_CONN_PROMPT_PORT_NUMBER.get(portNumber);
        }
        else
        {
          askPortNumber = INFO_LDAP_CONN_PROMPT_PORT_NUMBER.get(portNumber);
        }
        portNumber = app.readValidatedInput(askPortNumber, callback);
      }
      catch (ClientException e)
      {
        throw cannotReadConnectionParameters(e);
      }
    }
    copySecureArgsList.portArg.clearValues();
    copySecureArgsList.portArg.addValue(String.valueOf(portNumber));
    commandBuilder.addArgument(copySecureArgsList.portArg);
    // Handle certificate
  private void resolveTrustAndKeyManagers() throws ArgumentException {
    if ((state.useSSL || state.useStartTLS) && state.trustManager == null)
    {
      initializeTrustManager();
      initializeTrustAndKeyManagers();
    }
  }
  private void resolveCredentialLogin() throws ArgumentException
  {
    setAdminUidAndBindDnFromArgs();
    if (useKeyManager())
    {
      return;
    }
    promptForCredentialLoginIfRequired(secureArgsList.getBindDnArg().getValue(),
                                       secureArgsList.getAdminUidArg().getValue());
    final boolean onlyBindDnProvided = state.providedAdminUID != null || state.providedBindDN == null;
    if ((useAdminOrBindDn && onlyBindDnProvided)
     || (!useAdminOrBindDn && isAdminUidArgVisible()))
    {
      addArgToCommandBuilder(copySecureArgsList.getAdminUidArg(), getAdministratorUID());
    }
    else
    {
      addArgToCommandBuilder(copySecureArgsList.getBindDnArg(), getBindDN());
    }
  }
  private void setAdminUidAndBindDnFromArgs()
  {
    final Argument adminUid = secureArgsList.getAdminUidArg();
    final Argument bindDn = secureArgsList.getBindDnArg();
    state.providedAdminUID = (isAdminUidArgVisible() && adminUid.isPresent()) ? adminUid.getValue() : null;
    state.providedBindDN = ((useAdminOrBindDn || !isAdminUidArgVisible()) && bindDn.isPresent()) ? bindDn.getValue()
                                                                                                 : null;
    state.adminUID = !useKeyManager() ? adminUid.getValue() : null;
    state.bindDN = !useKeyManager() ? bindDn.getValue() : null;
  }
  private void resolveCredentialPassword() throws ArgumentException
  {
    if (secureArgsList.getBindPasswordArg().isPresent())
    {
      state.bindPassword = secureArgsList.getBindPasswordArg().getValue();
    }
    // Get the LDAP bind credentials.
    state.bindDN = secureArgsList.bindDnArg.getValue();
    state.adminUID= secureArgsList.adminUidArg.getValue();
    final boolean useAdmin = secureArgsList.useAdminUID();
    if (useAdmin && secureArgsList.adminUidArg.isPresent())
    if (useKeyManager())
    {
      state.providedAdminUID = state.adminUID;
      return;
    }
    else
    setBindPasswordFileFromArgs();
    final boolean addedPasswordFileArgument = secureArgsList.getBindPasswordFileArg().isPresent();
    if (!addedPasswordFileArgument && (state.bindPassword == null || "-".equals(state.bindPassword)))
    {
      state.providedAdminUID = null;
      promptForBindPasswordIfRequired();
    }
    if ((!useAdmin || useAdminOrBindDn) && secureArgsList.bindDnArg.isPresent())
    final Argument bindPassword = copySecureArgsList.getBindPasswordArg();
    bindPassword.clearValues();
    bindPassword.addValue(state.bindPassword);
    if (!addedPasswordFileArgument)
    {
      state.providedBindDN = state.bindDN;
      commandBuilder.addObfuscatedArgument(bindPassword);
    }
    else
  }
  private void setBindPasswordFileFromArgs() throws ArgumentException
  {
    final FileBasedArgument bindPasswordFile = secureArgsList.getBindPasswordFileArg();
    if (bindPasswordFile.isPresent())
    {
      state.providedBindDN = null;
    }
    boolean argIsPresent = state.providedAdminUID != null || state.providedBindDN != null;
    final String tmpBindDN = state.bindDN;
    final String tmpAdminUID = state.adminUID;
    if (state.keyManager == null)
    {
      if (app.isInteractive() && !argIsPresent)
      // Read from file if it exists.
      state.bindPassword = bindPasswordFile.getValue();
      if (state.bindPassword == null)
      {
        checkHeadingDisplayed();
        throw new ArgumentException(
            ERR_ERROR_NO_ADMIN_PASSWORD.get(isAdminUidArgVisible() ? state.adminUID : state.bindDN));
      }
      addArgToCommandBuilder(copySecureArgsList.getBindPasswordFileArg(), bindPasswordFile.getNameToValueMap());
    }
  }
        ValidationCallback<String> callback = new ValidationCallback<String>()
  private void resolveConnectTimeout() throws ArgumentException
  {
    state.connectTimeout = secureArgsList.getConnectTimeoutArg().getIntValue();
  }
  private void promptForHostNameIfRequired() throws ArgumentException
  {
    if (!app.isInteractive() || secureArgsList.getHostNameArg().isPresent())
    {
      return;
    }
    checkHeadingDisplayed();
    ValidationCallback<String> callback = new ValidationCallback<String>()
    {
      @Override
      public String validate(ConsoleApplication app, String rawInput) throws ClientException
      {
        final String input = rawInput.trim();
        if (input.length() == 0)
        {
          @Override
          public String validate(ConsoleApplication app, String input)
              throws ClientException
          {
            String ninput = input.trim();
            if (ninput.length() == 0)
            {
              if (useAdmin)
              {
                return tmpAdminUID;
              }
              else
              {
                return tmpBindDN;
              }
            }
            else
            {
              return ninput;
            }
          }
        };
          return state.hostName;
        }
        try
        {
          app.println();
          if (useAdminOrBindDn)
          {
            String def = state.adminUID != null ? state.adminUID : state.bindDN;
            String v =
                app.readValidatedInput(
                    INFO_LDAP_CONN_GLOBAL_ADMINISTRATOR_OR_BINDDN_PROMPT.get(def), callback);
            if (isDN(v))
            {
              state.bindDN = v;
              state.providedBindDN = v;
              state.adminUID = null;
              state.providedAdminUID = null;
            }
            else
            {
              state.bindDN = null;
              state.providedBindDN = null;
              state.adminUID = v;
              state.providedAdminUID = v;
            }
          }
          else if (useAdmin)
          {
            state.adminUID =
                app.readValidatedInput(INFO_LDAP_CONN_PROMPT_ADMINISTRATOR_UID.get(state.adminUID), callback);
            state.providedAdminUID = state.adminUID;
          }
          else
          {
            state.bindDN =
                app.readValidatedInput(INFO_LDAP_CONN_PROMPT_BIND_DN.get(state.bindDN), callback);
            state.providedBindDN = state.bindDN;
          }
          // Ensure that the prompted host is known
          InetAddress.getByName(input);
          return input;
        }
        catch (ClientException e)
        catch (UnknownHostException e)
        {
          throw cannotReadConnectionParameters(e);
          // Try again...
          app.println();
          app.println(ERR_LDAP_CONN_BAD_HOST_NAME.get(input));
          app.println();
          return null;
        }
      }
    };
    try
    {
      app.println();
      state.hostName = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_HOST_NAME.get(state.hostName), callback);
    }
    catch (ClientException e)
    {
      throw cannotReadConnectionParameters(e);
    }
  }
  private void promptForConnectionTypeIfRequired(final boolean canUseStartTLS)
  {
    final boolean valuesSetByProperty = secureArgsList.getUseSSLArg().isValueSetByProperty()
                                     && secureArgsList.getUseStartTLSArg().isValueSetByProperty();
    if (!app.isInteractive() || state.useSSL || state.useStartTLS || valuesSetByProperty)
    {
      return;
    }
    checkHeadingDisplayed();
    final MenuBuilder<Integer> builder = new MenuBuilder<>(app);
    builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_USE_SECURE_CTX.get());
    for (Protocol p : Protocol.values())
    {
      if ((!displayLdapIfSecureParameters && Protocol.LDAP.equals(p))
          || (!canUseStartTLS && Protocol.START_TLS.equals(p)))
      {
        continue;
      }
      final MenuResult<Integer> menuResult = MenuResult.success(p.getChoice());
      final int i = builder.addNumberedOption(p.message, menuResult);
      if (DEFAULT_PROMPT_PROTOCOL.equals(p))
      {
        builder.setDefault(INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE.get(i), menuResult);
      }
    }
    Menu<Integer> menu = builder.toMenu();
    try
    {
      final MenuResult<Integer> result = menu.run();
      throwIfMenuResultNotSucceeded(result);
      final int userChoice = result.getValue();
      if (Protocol.SSL.getChoice() == userChoice)
      {
        state.useSSL = true;
      }
      else if (Protocol.START_TLS.getChoice() == userChoice)
      {
        state.useStartTLS = true;
      }
    }
    catch (ClientException e)
    {
      throw new RuntimeException(e);
    }
  }
  private void promptForPortNumberIfRequired() throws ArgumentException
  {
    if (!app.isInteractive() || secureArgsList.getPortArg().isPresent())
    {
      return;
    }
    checkHeadingDisplayed();
    try
    {
      app.println();
      final LocalizableMessage askPortNumberMsg = secureArgsList.alwaysSSL() ?
          INFO_ADMIN_CONN_PROMPT_PORT_NUMBER.get(portNumber) :
          INFO_LDAP_CONN_PROMPT_PORT_NUMBER.get(portNumber);
      portNumber = app.readValidatedInput(askPortNumberMsg, portValidationCallback(portNumber));
    }
    catch (ClientException e)
    {
      throw cannotReadConnectionParameters(e);
    }
  }
  private void promptForCredentialLoginIfRequired(final String defaultBindDN, final String defaultAdminUID)
      throws ArgumentException
  {
    if (!app.isInteractive() || state.providedAdminUID != null || state.providedBindDN != null)
    {
      return;
    }
    checkHeadingDisplayed();
    ValidationCallback<String> callback = new ValidationCallback<String>()
    {
      @Override public String validate(ConsoleApplication app, String rawInput) throws ClientException
      {
        final String input = rawInput.trim();
        if (input.isEmpty())
        {
          return isAdminUidArgVisible() ? defaultAdminUID : defaultBindDN;
        }
        return input;
      }
    };
    try
    {
      app.println();
      if (useAdminOrBindDn)
      {
        boolean addAdmin = state.providedAdminUID != null;
        boolean addBindDN = state.providedBindDN != null;
        if (!addAdmin && !addBindDN)
        String def = state.adminUID != null ? state.adminUID : state.bindDN;
        String v = app.readValidatedInput(INFO_LDAP_CONN_GLOBAL_ADMINISTRATOR_OR_BINDDN_PROMPT.get(def), callback);
        if (isDN(v))
        {
          addAdmin = getAdministratorUID() != null;
          addBindDN = getBindDN() != null;
          state.bindDN = v;
          state.providedBindDN = v;
          state.adminUID = null;
          state.providedAdminUID = null;
        }
        if (addAdmin)
        else
        {
          copySecureArgsList.adminUidArg.clearValues();
          copySecureArgsList.adminUidArg.addValue(getAdministratorUID());
          commandBuilder.addArgument(copySecureArgsList.adminUidArg);
        }
        else if (addBindDN)
        {
          copySecureArgsList.bindDnArg.clearValues();
          copySecureArgsList.bindDnArg.addValue(getBindDN());
          commandBuilder.addArgument(copySecureArgsList.bindDnArg);
          state.bindDN = null;
          state.providedBindDN = null;
          state.adminUID = v;
          state.providedAdminUID = v;
        }
      }
      else if (useAdmin)
      else if (isAdminUidArgVisible())
      {
        copySecureArgsList.adminUidArg.clearValues();
        copySecureArgsList.adminUidArg.addValue(getAdministratorUID());
        commandBuilder.addArgument(copySecureArgsList.adminUidArg);
        state.adminUID = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_ADMINISTRATOR_UID.get(state.adminUID), callback);
        state.providedAdminUID = state.adminUID;
      }
      else
      {
        copySecureArgsList.bindDnArg.clearValues();
        copySecureArgsList.bindDnArg.addValue(getBindDN());
        commandBuilder.addArgument(copySecureArgsList.bindDnArg);
        state.bindDN = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_BIND_DN.get(state.bindDN), callback);
        state.providedBindDN = state.bindDN;
      }
    }
    else
    catch (ClientException e)
    {
      state.bindDN = null;
      state.adminUID = null;
      throw cannotReadConnectionParameters(e);
    }
    boolean addedPasswordFileArgument = false;
    if (secureArgsList.bindPasswordArg.isPresent())
    {
      state.bindPassword = secureArgsList.bindPasswordArg.getValue();
    }
    if (state.keyManager == null)
    {
      if (secureArgsList.bindPasswordFileArg.isPresent())
      {
        // Read from file if it exists.
        state.bindPassword = secureArgsList.bindPasswordFileArg.getValue();
        if (state.bindPassword == null)
        {
          if (useAdmin)
          {
            throw new ArgumentException(ERR_ERROR_NO_ADMIN_PASSWORD.get(state.adminUID));
          }
          else
          {
            throw new ArgumentException(ERR_ERROR_NO_ADMIN_PASSWORD.get(state.bindDN));
          }
        }
        copySecureArgsList.bindPasswordFileArg.clearValues();
        copySecureArgsList.bindPasswordFileArg.getNameToValueMap().putAll(
            secureArgsList.bindPasswordFileArg.getNameToValueMap());
        commandBuilder.addArgument(copySecureArgsList.bindPasswordFileArg);
        addedPasswordFileArgument = true;
      }
      else if (state.bindPassword == null || "-".equals(state.bindPassword))
      {
        // Read the password from the stdin.
        if (!app.isInteractive())
        {
          throw new ArgumentException(ERR_ERROR_BIND_PASSWORD_NONINTERACTIVE.get());
        }
        checkHeadingDisplayed();
        try
        {
          app.println();
          state.bindPassword = readPassword(state.getPrompt());
        }
        catch (Exception e)
        {
          throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
        }
      }
      copySecureArgsList.bindPasswordArg.clearValues();
      copySecureArgsList.bindPasswordArg.addValue(state.bindPassword);
      if (!addedPasswordFileArgument)
      {
        commandBuilder.addObfuscatedArgument(copySecureArgsList.bindPasswordArg);
      }
    }
    state.connectTimeout = secureArgsList.connectTimeoutArg.getIntValue();
  }
  private ArgumentException cannotReadConnectionParameters(ClientException e)
  private void promptForBindPasswordIfRequired() throws ArgumentException
  {
    return new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
  }
  private String readPassword(LocalizableMessage prompt) throws ClientException
  {
    final char[] pwd = app.readPassword(prompt);
    if (pwd != null)
    if (!app.isInteractive())
    {
      return String.valueOf(pwd);
      throw new ArgumentException(ERR_ERROR_BIND_PASSWORD_NONINTERACTIVE.get());
    }
    return null;
    checkHeadingDisplayed();
    try
    {
      state.bindPassword = readPassword(state.getPrompt());
    }
    catch (Exception e)
    {
      throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
    }
  }
  /**
@@ -837,205 +661,90 @@
   * @throws ArgumentException
   *           If an error occurs when getting args values.
   */
  private ApplicationTrustManager getTrustManagerInternal()
      throws ArgumentException
  private ApplicationTrustManager getTrustManagerInternal() throws ArgumentException
  {
    // Remove these arguments since this method might be called several times.
    commandBuilder.removeArgument(copySecureArgsList.trustAllArg);
    commandBuilder.removeArgument(copySecureArgsList.trustStorePathArg);
    commandBuilder.removeArgument(copySecureArgsList.trustStorePasswordArg);
    commandBuilder.removeArgument(copySecureArgsList.trustStorePasswordFileArg);
    commandBuilder.removeArguments(copySecureArgsList.getTrustAllArg(),
                                   copySecureArgsList.getTrustStorePathArg(),
                                   copySecureArgsList.getTrustStorePasswordArg(),
                                   copySecureArgsList.getTrustStorePasswordFileArg());
    // If we have the trustALL flag, don't do anything
    // just return null
    if (secureArgsList.trustAllArg.isPresent())
    final TrustMethod trustMethod = resolveTrustMethod();
    if (TrustMethod.TRUSTALL == trustMethod)
    {
      commandBuilder.addArgument(copySecureArgsList.trustAllArg);
      return null;
    }
    // Check if some trust manager info are set
    boolean weDontKnowTheTrustMethod =
        !secureArgsList.trustAllArg.isPresent()
        && !secureArgsList.trustStorePathArg.isPresent()
        && !secureArgsList.trustStorePasswordArg.isPresent()
        && !secureArgsList.trustStorePasswordFileArg.isPresent();
    boolean askForTrustStore = false;
    state.trustAll = secureArgsList.trustAllArg.isPresent();
    // Try to use the local instance trust store, to avoid certificate
    // validation when both the CLI and the server are in the same instance.
    if (weDontKnowTheTrustMethod && addLocalTrustStore())
    {
      weDontKnowTheTrustMethod = false;
    }
    if (app.isInteractive() && weDontKnowTheTrustMethod)
    {
      checkHeadingDisplayed();
      app.println();
      MenuBuilder<Integer> builder = new MenuBuilder<>(app);
      builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_METHOD.get());
      TrustMethod defaultTrustMethod = TrustMethod.DISPLAY_CERTIFICATE;
      for (TrustMethod t : TrustMethod.values())
      {
        int i =
            builder.addNumberedOption(t.getMenuMessage(), MenuResult.success(t
                .getChoice()));
        if (t.equals(defaultTrustMethod))
        {
          builder.setDefault(
              INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE
                  .get(Integer.valueOf(i)), MenuResult.success(t.getChoice()));
        }
      }
      Menu<Integer> menu = builder.toMenu();
      state.trustStoreInMemory = false;
      try
      {
        MenuResult<Integer> result = menu.run();
        if (result.isSuccess())
        {
          if (result.getValue().equals(TrustMethod.TRUSTALL.getChoice()))
          {
            commandBuilder.addArgument(copySecureArgsList.trustAllArg);
            state.trustAll = true;
            // If we have the trustALL flag, don't do anything
            // just return null
            return null;
          }
          else if (result.getValue().equals(TrustMethod.TRUSTSTORE.getChoice()))
          {
            // We have to ask for trust store info
            askForTrustStore = true;
          }
          else if (result.getValue().equals(
              TrustMethod.DISPLAY_CERTIFICATE.getChoice()))
          {
            // The certificate will be displayed to the user
            askForTrustStore = false;
            state.trustStoreInMemory = true;
            // There is no direct equivalent for this option, so propose the
            // trust all option as command-line argument.
            commandBuilder.addArgument(copySecureArgsList.trustAllArg);
          }
          else
          {
            // Should never happen.
            throw new RuntimeException();
          }
        }
        else
        {
          // Should never happen.
          throw new RuntimeException();
        }
      }
      catch (ClientException e)
      {
        throw new RuntimeException(e);
      }
    }
    // If we do not trust all server certificates, we have to get info
    // about trust store. First get the trust store path.
    state.truststorePath = secureArgsList.trustStorePathArg.getValue();
    if (app.isInteractive() && !secureArgsList.trustStorePathArg.isPresent() && askForTrustStore)
    {
      checkHeadingDisplayed();
      ValidationCallback<String> callback = new ValidationCallback<String>()
      {
        @Override
        public String validate(ConsoleApplication app, String input)
            throws ClientException
        {
          String ninput = input.trim();
          if (ninput.length() == 0)
          {
            app.println();
            app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
            app.println();
            return null;
          }
          File f = new File(ninput);
          if (f.exists() && f.canRead() && !f.isDirectory())
          {
            return ninput;
          }
          else
          {
            app.println();
            app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
            app.println();
            return null;
          }
        }
      };
      try
      {
        app.println();
        state.truststorePath = app.readValidatedInput(
                INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PATH.get(), callback);
      }
      catch (ClientException e)
      {
        throw cannotReadConnectionParameters(e);
      }
    }
    if (state.truststorePath != null)
    {
      copySecureArgsList.trustStorePathArg.clearValues();
      copySecureArgsList.trustStorePathArg.addValue(state.truststorePath);
      commandBuilder.addArgument(copySecureArgsList.trustStorePathArg);
    }
    // Then the truststore password.
    //  As the most common case is to have no password for truststore,
    // we don't ask it in the interactive mode.
    if (secureArgsList.trustStorePasswordArg.isPresent())
    {
      state.truststorePassword = secureArgsList.trustStorePasswordArg.getValue();
    }
    if (secureArgsList.trustStorePasswordFileArg.isPresent())
    {
      // Read from file if it exists.
      state.truststorePassword = secureArgsList.trustStorePasswordFileArg.getValue();
    }
    final boolean promptForTrustStore = TrustMethod.TRUSTSTORE == trustMethod;
    resolveTrustStorePath(promptForTrustStore);
    setTrustStorePassword();
    setTrustStorePasswordFromFile();
    if ("-".equals(state.truststorePassword))
    {
      // Read the password from the stdin.
      if (!app.isInteractive())
      {
        state.truststorePassword = null;
      }
      else
      {
        checkHeadingDisplayed();
        try
        {
          app.println();
          LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PASSWORD.get(state.truststorePath);
          state.truststorePassword = readPassword(prompt);
        }
        catch (Exception e)
        {
          throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
        }
      }
      promptForTrustStorePasswordIfRequired();
    }
    // We've got all the information to get the truststore manager
    return resolveTrustStore();
  }
  /** As the most common case is to have no password for trust store, we do not ask it in the interactive mode.*/
  private void setTrustStorePassword()
  {
    if (secureArgsList.getTrustStorePasswordArg().isPresent())
    {
      state.truststorePassword = secureArgsList.getTrustStorePasswordArg().getValue();
    }
  }
  private void setTrustStorePasswordFromFile()
  {
    if (secureArgsList.getTrustStorePasswordFileArg().isPresent())
    {
      state.truststorePassword = secureArgsList.getTrustStorePasswordFileArg().getValue();
    }
  }
  /** Return the trust method chosen by user or {@code null} if the information is not available. */
  private TrustMethod resolveTrustMethod()
  {
    state.trustAll = secureArgsList.getTrustAllArg().isPresent();
    // Check if some trust manager info are set
    boolean needPromptForTrustMethod = !state.trustAll
        && !secureArgsList.getTrustStorePathArg().isPresent()
        && !secureArgsList.getTrustStorePasswordArg().isPresent()
        && !secureArgsList.getTrustStorePasswordFileArg().isPresent();
    TrustMethod trustMethod = state.trustAll ? TrustMethod.TRUSTALL : null;
    // Try to use the local instance trust store, to avoid certificate
    // validation when both the CLI and the server are in the same instance.
    if (needPromptForTrustMethod && !useLocalTrustStoreIfPossible())
    {
      trustMethod = promptForTrustMethodIfRequired();
    }
    if (trustMethod != TrustMethod.TRUSTSTORE)
    {
      // There is no direct equivalent for the display certificate option,
      // so propose trust all option as command-line argument.
      commandBuilder.addArgument(copySecureArgsList.getTrustAllArg());
    }
    return trustMethod;
  }
  private void resolveTrustStorePath(final boolean promptForTrustStore) throws ArgumentException
  {
    state.truststorePath = secureArgsList.getTrustStorePathArg().getValue();
    if (promptForTrustStore)
    {
      promptForTrustStorePathIfRequired();
    }
    addArgToCommandBuilder(copySecureArgsList.getTrustStorePathArg(), state.truststorePath);
  }
  private ApplicationTrustManager resolveTrustStore() throws ArgumentException
  {
    try
    {
      state.truststore = KeyStore.getInstance(KeyStore.getDefaultType());
@@ -1043,14 +752,7 @@
      {
        try (FileInputStream fos = new FileInputStream(state.truststorePath))
        {
          if (state.truststorePassword != null)
          {
            state.truststore.load(fos, state.truststorePassword.toCharArray());
          }
          else
          {
            state.truststore.load(fos, null);
          }
          state.truststore.load(fos, state.truststorePassword != null ? state.truststorePassword.toCharArray() : null);
        }
      }
      else
@@ -1058,20 +760,14 @@
        state.truststore.load(null, null);
      }
      if (secureArgsList.trustStorePasswordFileArg.isPresent() && state.truststorePath != null)
      if (secureArgsList.getTrustStorePasswordFileArg().isPresent() && state.truststorePath != null)
      {
        copySecureArgsList.trustStorePasswordFileArg.clearValues();
        copySecureArgsList.trustStorePasswordFileArg.getNameToValueMap()
            .putAll(secureArgsList.trustStorePasswordFileArg.getNameToValueMap());
        commandBuilder.addArgument(copySecureArgsList.trustStorePasswordFileArg);
        addArgToCommandBuilder(copySecureArgsList.getTrustStorePasswordFileArg(),
            secureArgsList.getTrustStorePasswordFileArg().getNameToValueMap());
      }
      else if (state.truststorePassword != null && state.truststorePath != null)
      {
        // Only add the trust store password if there is one AND if the user
        // specified a trust store path.
        copySecureArgsList.trustStorePasswordArg.clearValues();
        copySecureArgsList.trustStorePasswordArg.addValue(state.truststorePassword);
        commandBuilder.addObfuscatedArgument(copySecureArgsList.trustStorePasswordArg);
        addObfuscatedArgToCommandBuilder(copySecureArgsList.getTrustStorePasswordArg(), state.truststorePassword);
      }
      return new ApplicationTrustManager(state.truststore);
@@ -1082,6 +778,91 @@
    }
  }
  private TrustMethod promptForTrustMethodIfRequired()
  {
    if (!app.isInteractive())
    {
      return null;
    }
    checkHeadingDisplayed();
    app.println();
    MenuBuilder<Integer> builder = new MenuBuilder<>(app);
    builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_METHOD.get());
    for (TrustMethod t : TrustMethod.values())
    {
      int i = builder.addNumberedOption(t.message, MenuResult.success(t.getChoice()));
      if (DEFAULT_PROMPT_TRUST_METHOD.equals(t))
      {
        builder.setDefault(
            INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE.get(i), MenuResult.success(t.getChoice()));
      }
    }
    Menu<Integer> menu = builder.toMenu();
    state.trustStoreInMemory = false;
    try
    {
      final MenuResult<Integer> result = menu.run();
      throwIfMenuResultNotSucceeded(result);
      final int userChoice = result.getValue();
      if (TrustMethod.TRUSTALL.getChoice() == userChoice)
      {
        state.trustAll = true;
      }
      else if (TrustMethod.DISPLAY_CERTIFICATE.getChoice() == userChoice)
      {
        state.trustStoreInMemory = true;
      }
      return TrustMethod.getTrustMethodForIndex(userChoice);
    }
    catch (ClientException e)
    {
      throw new RuntimeException(e);
    }
  }
  private void promptForTrustStorePathIfRequired() throws ArgumentException
  {
    if (!app.isInteractive() || secureArgsList.getTrustStorePathArg().isPresent())
    {
      return;
    }
    checkHeadingDisplayed();
    try
    {
      app.println();
      state.truststorePath = app.readValidatedInput(
          INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PATH.get(),
          filePathValidationCallback(!ALLOW_EMPTY_PATH, FILE_MUST_EXISTS));
    }
    catch (ClientException e)
    {
      throw cannotReadConnectionParameters(e);
    }
  }
  private void promptForTrustStorePasswordIfRequired() throws ArgumentException
  {
    if (!app.isInteractive())
    {
      return;
    }
    checkHeadingDisplayed();
    try
    {
      state.truststorePassword = readPassword(
          INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PASSWORD.get(state.truststorePath));
    }
    catch (Exception e)
    {
      throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
    }
  }
  /**
   * Get the key manager.
   *
@@ -1092,218 +873,283 @@
  private KeyManager getKeyManagerInternal() throws ArgumentException
  {
    //  Remove these arguments since this method might be called several times.
    commandBuilder.removeArgument(copySecureArgsList.certNicknameArg);
    commandBuilder.removeArgument(copySecureArgsList.keyStorePathArg);
    commandBuilder.removeArgument(copySecureArgsList.keyStorePasswordArg);
    commandBuilder.removeArgument(copySecureArgsList.keyStorePasswordFileArg);
    commandBuilder.removeArguments(copySecureArgsList.getCertNicknameArg(),
                                   copySecureArgsList.getKeyStorePathArg(),
                                   copySecureArgsList.getKeyStorePasswordArg(),
                                   copySecureArgsList.getKeyStorePasswordFileArg());
    // Do we need client side authentication ?
    // If one of the client side authentication args is set, we assume
    // that we
    // need client side authentication.
    boolean weDontKnowIfWeNeedKeystore =
        !secureArgsList.keyStorePathArg.isPresent()
        && !secureArgsList.keyStorePasswordArg.isPresent()
        && !secureArgsList.keyStorePasswordFileArg.isPresent()
        && !secureArgsList.certNicknameArg.isPresent();
    // We don't have specific key manager parameter.
    // We assume that no client side authentication is required
    // Client side authentication is not the common use case. As a
    // consequence, interactive mode doesn't add an extra question
    // which will be in most cases useless.
    if (weDontKnowIfWeNeedKeystore)
    if (!secureArgsList.getKeyStorePathArg().isPresent()
     && !secureArgsList.getKeyStorePasswordArg().isPresent()
     && !secureArgsList.getKeyStorePasswordFileArg().isPresent()
     && !secureArgsList.getCertNicknameArg().isPresent())
    {
      // If no one of these parameters above are set, we assume that we do not need client side authentication.
      // Client side authentication is not the common use case so interactive mode doesn't add an extra question.
      return null;
    }
    // Get info about keystore. First get the keystore path.
    state.keystorePath = secureArgsList.keyStorePathArg.getValue();
    if (app.isInteractive() && !secureArgsList.keyStorePathArg.isPresent())
    resolveKeyStorePath();
    resolveKeyStorePassword();
    final KeyStore keystore = createKeyStore();
    resolveCertificateNickname(keystore);
    final ApplicationKeyManager keyManager = new ApplicationKeyManager(keystore, state.keystorePassword.toCharArray());
    addKeyStorePasswordArgToCommandBuilder();
    if (state.certifNickname != null)
    {
      checkHeadingDisplayed();
      ValidationCallback<String> callback = new ValidationCallback<String>()
      {
        @Override
        public String validate(ConsoleApplication app, String input)
            throws ClientException
        {
          String ninput = input.trim();
          if (ninput.length() == 0)
          {
            return ninput;
          }
          File f = new File(ninput);
          if (f.exists() && f.canRead() && !f.isDirectory())
          {
            return ninput;
          }
          else
          {
            app.println();
            app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
            app.println();
            return null;
          }
        }
      };
      try
      {
        app.println();
        state.keystorePath = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PATH.get(), callback);
      }
      catch (ClientException e)
      {
        throw cannotReadConnectionParameters(e);
      }
      addArgToCommandBuilder(copySecureArgsList.getCertNicknameArg(), state.certifNickname);
      return SelectableCertificateKeyManager.wrap(
          new KeyManager[] { keyManager }, CollectionUtils.newTreeSet(state.certifNickname))[0];
    }
    if (state.keystorePath != null)
    return keyManager;
  }
  private void resolveKeyStorePath() throws ArgumentException
  {
    state.keyStorePath = secureArgsList.getKeyStorePathArg().getValue();
    promptForKeyStorePathIfRequired();
    if (state.keyStorePath == null)
    {
      copySecureArgsList.keyStorePathArg.clearValues();
      copySecureArgsList.keyStorePathArg.addValue(state.keystorePath);
      commandBuilder.addArgument(copySecureArgsList.keyStorePathArg);
    }
    else
    {
      // KeystorePath is null. Either it's unspecified or there's a pb
      // We should throw an exception here, anyway since code below will
      // anyway
      throw new ArgumentException(ERR_ERROR_INCOMPATIBLE_PROPERTY_MOD.get("null keystorePath"));
    }
    addArgToCommandBuilder(copySecureArgsList.getKeyStorePathArg(), state.keyStorePath);
  }
    // Then the keystore password.
    state.keystorePassword = secureArgsList.keyStorePasswordArg.getValue();
  private void resolveKeyStorePassword() throws ArgumentException
  {
    state.keystorePassword = secureArgsList.getKeyStorePasswordArg().getValue();
    if (secureArgsList.keyStorePasswordFileArg.isPresent())
    if (secureArgsList.getKeyStorePasswordFileArg().isPresent())
    {
      // Read from file if it exists.
      state.keystorePassword = secureArgsList.keyStorePasswordFileArg.getValue();
      state.keystorePassword = secureArgsList.getKeyStorePasswordFileArg().getValue();
      if (state.keystorePassword == null)
      {
        throw new ArgumentException(ERR_ERROR_NO_ADMIN_PASSWORD.get(state.keystorePassword));
        throw new ArgumentException(ERR_INSTALLDS_NO_KEYSTORE_PASSWORD.get(
            secureArgsList.getKeyStorePathArg().getLongIdentifier(),
            secureArgsList.getKeyStorePasswordFileArg().getLongIdentifier()));
      }
    }
    else if (state.keystorePassword == null || "-".equals(state.keystorePassword))
    {
      // Read the password from the stdin.
      if (!app.isInteractive())
      {
        throw new ArgumentException(ERR_ERROR_BIND_PASSWORD_NONINTERACTIVE.get());
      }
      checkHeadingDisplayed();
      try
      {
        app.println();
        LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD.get(state.keystorePath);
        state.keystorePassword = readPassword(prompt);
      }
      catch (Exception e)
      {
        throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
      }
      promptForKeyStorePasswordIfRequired();
    }
  }
    // finally the certificate name, if needed.
    KeyStore keystore = null;
    Enumeration<String> aliasesEnum = null;
    try (FileInputStream fos = new FileInputStream(state.keystorePath))
  private KeyStore createKeyStore() throws ArgumentException
  {
    try (FileInputStream fos = new FileInputStream(state.keyStorePath))
    {
      keystore = KeyStore.getInstance(KeyStore.getDefaultType());
      final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
      keystore.load(fos, state.keystorePassword.toCharArray());
      aliasesEnum = keystore.aliases();
      return keystore;
    }
    catch (Exception e)
    {
      throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
    }
  }
    state.certifNickname = secureArgsList.certNicknameArg.getValue();
    if (app.isInteractive() && !secureArgsList.certNicknameArg.isPresent() && aliasesEnum.hasMoreElements())
  private void resolveCertificateNickname(final KeyStore keystore) throws ArgumentException
  {
    state.certifNickname = secureArgsList.getCertNicknameArg().getValue();
    try
    {
      checkHeadingDisplayed();
      promptForCertificateNicknameIfRequired(keystore, keystore.aliases());
    }
    catch (final KeyStoreException e)
    {
      throw new ArgumentException(ERR_RESOLVE_KEYSTORE_ALIASES.get(e.getMessage()), e);
    }
  }
      try
  private void promptForKeyStorePathIfRequired() throws ArgumentException
  {
    if (!app.isInteractive() || secureArgsList.getKeyStorePathArg().isPresent())
    {
      return;
    }
    checkHeadingDisplayed();
    try
    {
      app.println();
      state.keyStorePath = app.readValidatedInput(INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PATH.get(),
                                                  filePathValidationCallback(ALLOW_EMPTY_PATH, FILE_MUST_EXISTS));
    }
    catch (ClientException e)
    {
      throw cannotReadConnectionParameters(e);
    }
  }
  private void promptForKeyStorePasswordIfRequired() throws ArgumentException
  {
    if (!app.isInteractive())
    {
      throw new ArgumentException(ERR_ERROR_BIND_PASSWORD_NONINTERACTIVE.get());
    }
    checkHeadingDisplayed();
    try
    {
      state.keystorePassword = readPassword(INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD.get(state.keyStorePath));
    }
    catch (Exception e)
    {
      throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
    }
  }
  private void promptForCertificateNicknameIfRequired(KeyStore keystore, Enumeration<String> aliasesEnum)
      throws ArgumentException
  {
    if (!app.isInteractive() || secureArgsList.getCertNicknameArg().isPresent() || !aliasesEnum.hasMoreElements())
    {
      return;
    }
    state.certifNickname = null;
    checkHeadingDisplayed();
    try
    {
      MenuBuilder<String> builder = new MenuBuilder<>(app);
      builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_ALIASES.get());
      int certificateNumber = 0;
      while (aliasesEnum.hasMoreElements())
      {
        MenuBuilder<String> builder = new MenuBuilder<>(app);
        builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_ALIASES.get());
        int certificateNumber = 0;
        for (; aliasesEnum.hasMoreElements();)
        final String alias = aliasesEnum.nextElement();
        if (keystore.isKeyEntry(alias))
        {
          String alias = aliasesEnum.nextElement();
          if (keystore.isKeyEntry(alias))
          {
            X509Certificate certif =
                (X509Certificate) keystore.getCertificate(alias);
            certificateNumber++;
            builder.addNumberedOption(
                    INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_ALIAS.get(alias,
                        certif.getSubjectDN().getName()), MenuResult.success(alias));
          }
        }
        if (certificateNumber > 1)
        {
          app.println();
          Menu<String> menu = builder.toMenu();
          MenuResult<String> result = menu.run();
          if (result.isSuccess())
          {
            state.certifNickname = result.getValue();
          }
          else
          {
            // Should never happen.
            throw new RuntimeException();
          }
        }
        else
        {
          state.certifNickname = null;
          certificateNumber++;
          X509Certificate certif = (X509Certificate) keystore.getCertificate(alias);
          builder.addNumberedOption(INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_ALIAS.get(
                                                                                alias, certif.getSubjectDN().getName()),
                                    MenuResult.success(alias));
        }
      }
      catch (KeyStoreException e)
      if (certificateNumber > 1)
      {
        throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
      }
      catch (ClientException e)
      {
        throw cannotReadConnectionParameters(e);
        app.println();
        Menu<String> menu = builder.toMenu();
        final MenuResult<String> result = menu.run();
        throwIfMenuResultNotSucceeded(result);
        state.certifNickname = result.getValue();
      }
    }
    // We'we got all the information to get the keys manager
    ApplicationKeyManager akm =
        new ApplicationKeyManager(keystore, state.keystorePassword.toCharArray());
    if (secureArgsList.keyStorePasswordFileArg.isPresent())
    catch (KeyStoreException e)
    {
      copySecureArgsList.keyStorePasswordFileArg.clearValues();
      copySecureArgsList.keyStorePasswordFileArg.getNameToValueMap().putAll(
          secureArgsList.keyStorePasswordFileArg.getNameToValueMap());
      commandBuilder.addArgument(copySecureArgsList.keyStorePasswordFileArg);
      throw new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
    }
    catch (ClientException e)
    {
      throw cannotReadConnectionParameters(e);
    }
  }
  private void addKeyStorePasswordArgToCommandBuilder()
  {
    if (secureArgsList.getKeyStorePasswordFileArg().isPresent())
    {
      addArgToCommandBuilder(copySecureArgsList.getKeyStorePasswordFileArg(),
          secureArgsList.getKeyStorePasswordFileArg().getNameToValueMap());
    }
    else if (state.keystorePassword != null)
    {
      copySecureArgsList.keyStorePasswordArg.clearValues();
      copySecureArgsList.keyStorePasswordArg.addValue(state.keystorePassword);
      commandBuilder.addObfuscatedArgument(copySecureArgsList.keyStorePasswordArg);
      addObfuscatedArgToCommandBuilder(copySecureArgsList.getKeyStorePasswordArg(), state.keystorePassword);
    }
  }
    if (state.certifNickname != null)
  private void addConnectionTypeToCommandBuilder()
  {
    if (state.useSSL)
    {
      copySecureArgsList.certNicknameArg.clearValues();
      copySecureArgsList.certNicknameArg.addValue(state.certifNickname);
      return SelectableCertificateKeyManager.wrap(
          new KeyManager[] { akm },
          CollectionUtils.newTreeSet(state.certifNickname))[0];
      commandBuilder.addArgument(copySecureArgsList.getUseSSLArg());
    }
    return akm;
    else if (state.useStartTLS)
    {
      commandBuilder.addArgument(copySecureArgsList.getUseStartTLSArg());
    }
  }
  private void addArgToCommandBuilder(final Argument arg, final String value)
  {
    addArgToCommandBuilder(arg, value, false);
  }
  private void addObfuscatedArgToCommandBuilder(final Argument arg, final String value)
  {
    addArgToCommandBuilder(arg, value, true);
  }
  private void addArgToCommandBuilder(final Argument arg, final String value, final boolean obfuscated)
  {
    if (value != null)
    {
      arg.clearValues();
      arg.addValue(value);
      commandBuilder.addArgument(arg);
    }
  }
  private void addArgToCommandBuilder(final FileBasedArgument arg, final Map<String, String> nameToValueMap)
  {
    arg.clearValues();
    arg.getNameToValueMap().putAll(nameToValueMap);
    commandBuilder.addArgument(arg);
  }
  private ArgumentException cannotReadConnectionParameters(ClientException e)
  {
    return new ArgumentException(ERR_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(e.getMessage()), e.getCause());
  }
  private String readPassword(LocalizableMessage prompt) throws ClientException
  {
    app.println();
    final char[] pwd = app.readPassword(prompt);
    if (pwd != null)
    {
      return String.valueOf(pwd);
    }
    return null;
  }
  private ValidationCallback<String> filePathValidationCallback(
      final boolean allowEmptyPath, final boolean checkExistenceAndReadability)
  {
    return new ValidationCallback<String>()
    {
      @Override
      public String validate(final ConsoleApplication app, final String filePathUserInput) throws ClientException
      {
        final String filePath = filePathUserInput.trim();
        final File f = new File(filePath);
        if ((!allowEmptyPath && filePath.isEmpty())
            || f.isDirectory()
            || (checkExistenceAndReadability && !(f.exists() && f.canRead())))
        {
          app.println();
          app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
          app.println();
          return null;
        }
        return filePath;
      }
    };
  }
  /** Returns {@code true} if client script uses the adminUID argument. */
  private boolean isAdminUidArgVisible()
  {
    return !secureArgsList.getAdminUidArg().isHidden();
  }
  private boolean useKeyManager()
  {
    return state.keyManager != null;
  }
  /**
@@ -1374,10 +1220,6 @@
    {
      return state.getAdminOrBindDN();
    }
    else if (secureArgsList.useAdminUID())
    {
      return getAdministratorDN(state.adminUID);
    }
    else
    {
      return state.bindDN;
@@ -1480,219 +1322,196 @@
   *          the host we tried to connect and that presented the certificate.
   * @return true if the server certificate is trusted.
   */
  public boolean checkServerCertificate(X509Certificate[] chain,
      String authType, String host)
  public boolean checkServerCertificate(final X509Certificate[] chain, final String authType, final String host)
  {
    if (state.trustManager == null)
    {
      try
      {
        initializeTrustManager();
        initializeTrustAndKeyManagers();
      }
      catch (ArgumentException ae)
      {
        // Should not occur
        // Should not append because this.run() should has been called at this stage.
        throw new RuntimeException(ae);
      }
    }
    app.println();
    app.println(INFO_LDAP_CONN_PROMPT_SECURITY_SERVER_CERTIFICATE.get());
    app.println();
    for (int i = 0; i < chain.length; i++)
    {
      // Certificate DN
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_USER_DN.get(chain[i].getSubjectDN()));
      // certificate validity
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_VALIDITY.get(
          chain[i].getNotBefore(), chain[i].getNotAfter()));
      // certificate Issuer
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_ISSUER.get(chain[i].getIssuerDN()));
      if (i + 1 < chain.length)
      {
        app.println();
        app.println();
      }
    }
    printCertificateChain(chain);
    MenuBuilder<Integer> builder = new MenuBuilder<>(app);
    builder.setPrompt(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION.get());
    TrustOption defaultTrustMethod = TrustOption.SESSION;
    for (TrustOption t : TrustOption.values())
    {
      int i = builder.addNumberedOption(t.getMenuMessage(), MenuResult.success(t.getChoice()));
      if (t.equals(defaultTrustMethod))
      final MenuResult<Integer> result = MenuResult.success(t.getChoice());
      int i = builder.addNumberedOption(t.message, result);
      if (DEFAULT_PROMPT_TRUST_OPTION.equals(t))
      {
        builder.setDefault(INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE.get(
            Integer.valueOf(i)), MenuResult.success(t.getChoice()));
        builder.setDefault(INFO_LDAP_CONN_PROMPT_SECURITY_PROTOCOL_DEFAULT_CHOICE.get(i), result);
      }
    }
    app.println();
    app.println();
    Menu<Integer> menu = builder.toMenu();
    while (true)
    final Menu<Integer> menu = builder.toMenu();
    try
    {
      try
      boolean promptAgain;
      int userChoice;
      do
      {
        MenuResult<Integer> result = menu.run();
        if (result.isSuccess())
        promptAgain = false;
        final MenuResult<Integer> result = menu.run();
        throwIfMenuResultNotSucceeded(result);
        userChoice = result.getValue();
        if (TrustOption.CERTIFICATE_DETAILS.getChoice() == userChoice)
        {
          if (result.getValue().equals(TrustOption.UNTRUSTED.getChoice()))
          {
            return false;
          }
          if (result.getValue().equals(
              TrustOption.CERTIFICATE_DETAILS.getChoice()))
          {
            for (X509Certificate cert : chain)
            {
              app.println();
              app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE.get(cert));
            }
            continue;
          }
          // We should add it in the memory truststore
          for (X509Certificate cert : chain)
          {
            String alias = cert.getSubjectDN().getName();
            try
            {
              state.truststore.setCertificateEntry(alias, cert);
            }
            catch (KeyStoreException e1)
            {
              // What else should we do?
              return false;
            }
          }
          // Update the trust manager
          if (state.trustManager == null)
          {
            state.trustManager = new ApplicationTrustManager(state.truststore);
          }
          if (authType != null && host != null)
          {
            // Update the trust manager with the new certificate
            state.trustManager.acceptCertificate(chain, authType, host);
          }
          else
          {
            // Do a full reset of the contents of the keystore.
            state.trustManager = new ApplicationTrustManager(state.truststore);
          }
          if (result.getValue().equals(TrustOption.PERMAMENT.getChoice()))
          {
            ValidationCallback<String> callback =
                new ValidationCallback<String>()
                {
                  @Override
                  public String validate(ConsoleApplication app, String input)
                      throws ClientException
                  {
                    String ninput = input.trim();
                    if (ninput.length() == 0)
                    {
                      app.println();
                      app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
                      app.println();
                      return null;
                    }
                    File f = new File(ninput);
                    if (!f.isDirectory())
                    {
                      return ninput;
                    }
                    else
                    {
                      app.println();
                      app.println(ERR_LDAP_CONN_PROMPT_SECURITY_INVALID_FILE_PATH.get());
                      app.println();
                      return null;
                    }
                  }
                };
            String truststorePath;
            try
            {
              app.println();
              truststorePath =
                  app.readValidatedInput(INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PATH.get(), callback);
            }
            catch (ClientException e)
            {
              return true;
            }
            // Read the password from the stdin.
            String truststorePassword;
            try
            {
              app.println();
              LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD.get(truststorePath);
              truststorePassword = readPassword(prompt);
            }
            catch (Exception e)
            {
              return true;
            }
            try
            {
              KeyStore ts = KeyStore.getInstance("JKS");
              FileInputStream fis;
              try
              {
                fis = new FileInputStream(truststorePath);
              }
              catch (FileNotFoundException e)
              {
                fis = null;
              }
              ts.load(fis, truststorePassword.toCharArray());
              if (fis != null)
              {
                fis.close();
              }
              for (X509Certificate cert : chain)
              {
                String alias = cert.getSubjectDN().getName();
                ts.setCertificateEntry(alias, cert);
              }
              FileOutputStream fos = new FileOutputStream(truststorePath);
              try
              {
                ts.store(fos, truststorePassword.toCharArray());
              }
              finally
              {
                fos.close();
              }
            }
            catch (Exception e)
            {
              return true;
            }
          }
          return true;
        }
        else
        {
          // Should never happen.
          throw new RuntimeException();
          promptAgain = true;
          printCertificateDetails(chain);
        }
      }
      catch (ClientException cliE)
      while (promptAgain);
      return trustCertificate(TrustOption.getTrustOptionForIndex(userChoice), chain, authType, host);
    }
    catch (ClientException e)
    {
      throw new RuntimeException(e);
    }
  }
  private void printCertificateChain(X509Certificate[] chain)
  {
    app.println();
    app.println(INFO_LDAP_CONN_PROMPT_SECURITY_SERVER_CERTIFICATE.get());
    app.println();
    boolean printSeparatorLines = false;
    for (final X509Certificate cert : chain)
    {
      if (!printSeparatorLines)
      {
        throw new RuntimeException(cliE);
        app.println();
        app.println();
        printSeparatorLines = true;
      }
      // Certificate DN
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_USER_DN.get(cert.getSubjectDN()));
      // certificate validity
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_VALIDITY.get(
          cert.getNotBefore(), cert.getNotAfter()));
      // certificate Issuer
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_ISSUER.get(cert.getIssuerDN()));
    }
  }
  private void printCertificateDetails(X509Certificate[] chain)
  {
    for (X509Certificate cert : chain)
    {
      app.println();
      app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE.get(cert));
    }
  }
  private boolean trustCertificate(final TrustOption trustOption, final X509Certificate[] chain,
      final String authType, final String host) throws ClientException
  {
    try
    {
      switch (trustOption)
      {
      case SESSION:
        updateTrustManager(chain, authType, host);
        return true;
      case PERMAMENT:
        updateTrustManager(chain, authType, host);
        try
        {
          trustCertificatePermanently(chain);
        }
        catch (Exception e)
        {
          app.println(ERR_TRUSTING_CERTIFICATE_PERMANENTLY.get(e.getMessage()));
        }
        return true;
      case UNTRUSTED:
      default:
        return false;
      }
    }
    catch (KeyStoreException e)
    {
      app.println(ERR_TRUSTING_CERTIFICATE.get(e.getMessage()));
      return false;
    }
  }
  private void updateTrustManager(X509Certificate[] chain, String authType, String host) throws KeyStoreException
  {
    // User choice if to add the certificate to the trust store for the current session or permanently.
    for (final X509Certificate cert : chain)
    {
      state.truststore.setCertificateEntry(cert.getSubjectDN().getName(), cert);
    }
    // Update the trust manager
    if (state.trustManager == null)
    {
      state.trustManager = new ApplicationTrustManager(state.truststore);
    }
    if (authType != null && host != null)
    {
      // Update the trust manager with the new certificate
      state.trustManager.acceptCertificate(chain, authType, host);
    }
    else
    {
      // Do a full reset of the contents of the keystore.
      state.trustManager = new ApplicationTrustManager(state.truststore);
    }
  }
  private void trustCertificatePermanently(final X509Certificate[] chain) throws Exception
  {
    app.println();
    final String trustStorePath = app.readValidatedInput(
        INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PATH.get(),
        filePathValidationCallback(!ALLOW_EMPTY_PATH, !FILE_MUST_EXISTS));
    // Read the password from the stdin.
    final String trustStorePasswordStr = readPassword(
        INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD.get(trustStorePath));
    final KeyStore keyStore = KeyStore.getInstance("JKS");
    final char[] trustStorePassword = trustStorePasswordStr.toCharArray();
    loadKeyStoreFromFile(keyStore, trustStorePath, trustStorePassword);
    for (final X509Certificate cert : chain)
    {
      keyStore.setCertificateEntry(cert.getSubjectDN().getName(), cert);
    }
    try (final FileOutputStream trustStoreOutputFile = new FileOutputStream(trustStorePath))
    {
      keyStore.store(trustStoreOutputFile, trustStorePassword);
    }
  }
  private void loadKeyStoreFromFile(
      final KeyStore keyStore, final String trustStorePath, final char[] trustStorePassword) throws Exception
  {
      try (FileInputStream inputStream = new FileInputStream(trustStorePath))
      {
        keyStore.load(inputStream, trustStorePassword);
      }
      catch (FileNotFoundException ignored)
      {
        // create empty keystore
        keyStore.load(null, trustStorePassword);
      }
  }
  /**
@@ -1718,7 +1537,7 @@
    if (state.useSSL)
    {
      SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory();
      sslConnectionFactory.init(getTrustManager() == null, state.keystorePath,
      sslConnectionFactory.init(getTrustManager() == null, state.keyStorePath,
          state.keystorePassword, state.certifNickname, state.truststorePath, state.truststorePassword);
      options.setSSLConnectionFactory(sslConnectionFactory);
    }
@@ -1729,9 +1548,8 @@
  /**
   * Prompts the user to accept the certificate.
   *
   * @param t
   *          the throwable that was generated because the certificate was not
   *          trusted.
   * @param errorRaised
   *          the error raised because the certificate was not trusted.
   * @param usedTrustManager
   *          the trustManager used when trying to establish the connection.
   * @param usedUrl
@@ -1741,85 +1559,58 @@
   * @return {@code true} if the user accepted the certificate and
   *         {@code false} otherwise.
   */
  public boolean promptForCertificateConfirmation(Throwable t,
  public boolean promptForCertificateConfirmation(Throwable errorRaised,
      ApplicationTrustManager usedTrustManager, String usedUrl, LocalizedLogger logger)
  {
    ApplicationTrustManager.Cause cause;
    if (usedTrustManager != null)
    final ApplicationTrustManager.Cause cause = usedTrustManager != null ? usedTrustManager.getLastRefusedCause()
                                                                         : null;
    logger.debug(INFO_CERTIFICATE_EXCEPTION_CAUSE.get(cause));
    if (cause == null)
    {
      cause = usedTrustManager.getLastRefusedCause();
      app.println(getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), errorRaised));
      return false;
    }
    String host;
    int port;
    try
    {
      URI uri = new URI(usedUrl);
      host = uri.getHost();
      port = uri.getPort();
    }
    catch (URISyntaxException e)
    {
      logger.warn(ERROR_CERTIFICATE_PARSING_URL.get(usedUrl, e));
      host = INFO_NOT_AVAILABLE_LABEL.get().toString();
      port = -1;
    }
    final String authType = usedTrustManager.getLastRefusedAuthType();
    if (authType == null)
    {
      logger.warn(ERROR_CERTIFICATE_NULL_AUTH_TYPE.get());
    }
    else
    {
      cause = null;
    }
    if (logger != null)
    {
      logger.debug(LocalizableMessage.raw("Certificate exception cause: " + cause));
      app.println(ApplicationTrustManager.Cause.NOT_TRUSTED.equals(authType)
          ? INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI.get(host, port)
          : INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI.get(host, port, host, host, port));
    }
    if (cause != null)
    final X509Certificate[] chain = usedTrustManager.getLastRefusedChain();
    if (chain == null)
    {
      String h;
      int p;
      try
      {
        URI uri = new URI(usedUrl);
        h = uri.getHost();
        p = uri.getPort();
      }
      catch (Throwable t1)
      {
        printLogger(logger, "Error parsing ldap url of ldap url. " + t1);
        h = INFO_NOT_AVAILABLE_LABEL.get().toString();
        p = -1;
      }
      String authType = usedTrustManager.getLastRefusedAuthType();
      if (authType == null)
      {
        printLogger(logger, "Null auth type for this certificate exception.");
      }
      else
      {
        LocalizableMessage msg;
        if (authType.equals(ApplicationTrustManager.Cause.NOT_TRUSTED))
        {
          msg = INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI.get(h, p);
        }
        else
        {
          msg = INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI.get(h, p, h, h, p);
        }
        app.println(msg);
      }
      X509Certificate[] chain = usedTrustManager.getLastRefusedChain();
      if (chain == null)
      {
        printLogger(logger, "Null chain for this certificate exception.");
        return false;
      }
      if (h == null)
      {
        printLogger(logger, "Null host name for this certificate exception.");
      }
      return checkServerCertificate(chain, authType, h);
      logger.warn(ERROR_CERTIFICATE_NULL_CHAIN.get());
      return false;
    }
    else
    if (host == null)
    {
      app.println(getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), t));
      logger.warn(ERROR_CERTIFICATE_NULL_HOST_NAME.get());
    }
    return false;
  }
  private void printLogger(final LocalizedLogger logger,
      final String msg)
  {
    if (logger != null)
    {
      logger.warn(LocalizableMessage.raw(msg));
    }
    return checkServerCertificate(chain, authType, host);
  }
  /**
@@ -1860,20 +1651,9 @@
  }
  /**
   * Tells whether during interaction we can ask for both the DN or the admin
   * UID.
   *
   * @return {@code true} if during interaction we can ask for both the DN
   *         and the admin UID and {@code false} otherwise.
   */
  public boolean isUseAdminOrBindDn()
  {
    return useAdminOrBindDn;
  }
  /**
   * Tells whether we can ask during interaction for both the DN and the admin
   * UID or not.
   * Default value is {@code false}.
   *
   * @param useAdminOrBindDn
   *          whether we can ask for both the DN and the admin UID during
@@ -1893,8 +1673,7 @@
   *          whether propose LDAP as protocol even if the user provided
   *          security parameters or not.
   */
  public void setDisplayLdapIfSecureParameters(
      boolean displayLdapIfSecureParameters)
  public void setDisplayLdapIfSecureParameters(boolean displayLdapIfSecureParameters)
  {
    this.displayLdapIfSecureParameters = displayLdapIfSecureParameters;
  }
@@ -1919,7 +1698,7 @@
  {
    if (!state.trustManagerInitialized)
    {
      initializeTrustManager();
      initializeTrustAndKeyManagers();
    }
  }
@@ -1948,46 +1727,46 @@
    resetConnectionArguments();
    if (hostName != null)
    {
      secureArgsList.hostNameArg.addValue(hostName);
      secureArgsList.hostNameArg.setPresent(true);
      secureArgsList.getHostNameArg().addValue(hostName);
      secureArgsList.getHostNameArg().setPresent(true);
    }
    // resetConnectionArguments does not clear the values for the port
    secureArgsList.portArg.clearValues();
    secureArgsList.getPortArg().clearValues();
    if (port != -1)
    {
      secureArgsList.portArg.addValue(String.valueOf(port));
      secureArgsList.portArg.setPresent(true);
      secureArgsList.getPortArg().addValue(String.valueOf(port));
      secureArgsList.getPortArg().setPresent(true);
    }
    else
    {
      // This is done to be able to call IntegerArgument.getIntValue()
      secureArgsList.portArg.addValue(secureArgsList.portArg.getDefaultValue());
      secureArgsList.getPortArg().addValue(secureArgsList.getPortArg().getDefaultValue());
    }
    secureArgsList.useSSLArg.setPresent(state.useSSL);
    secureArgsList.useStartTLSArg.setPresent(state.useStartTLS);
    secureArgsList.getUseSSLArg().setPresent(state.useSSL);
    secureArgsList.getUseStartTLSArg().setPresent(state.useStartTLS);
    if (adminUid != null)
    {
      secureArgsList.adminUidArg.addValue(adminUid);
      secureArgsList.adminUidArg.setPresent(true);
      secureArgsList.getAdminUidArg().addValue(adminUid);
      secureArgsList.getAdminUidArg().setPresent(true);
    }
    if (bindDn != null)
    {
      secureArgsList.bindDnArg.addValue(bindDn);
      secureArgsList.bindDnArg.setPresent(true);
      secureArgsList.getBindDnArg().addValue(bindDn);
      secureArgsList.getBindDnArg().setPresent(true);
    }
    if (pwdFile != null)
    {
      secureArgsList.bindPasswordFileArg.getNameToValueMap().putAll(pwdFile);
      secureArgsList.getBindPasswordFileArg().getNameToValueMap().putAll(pwdFile);
      for (String value : pwdFile.keySet())
      {
        secureArgsList.bindPasswordFileArg.addValue(value);
        secureArgsList.getBindPasswordFileArg().addValue(value);
      }
      secureArgsList.bindPasswordFileArg.setPresent(true);
      secureArgsList.getBindPasswordFileArg().setPresent(true);
    }
    else if (bindPwd != null)
    {
      secureArgsList.bindPasswordArg.addValue(bindPwd);
      secureArgsList.bindPasswordArg.setPresent(true);
      secureArgsList.getBindPasswordArg().addValue(bindPwd);
      secureArgsList.getBindPasswordArg().setPresent(true);
    }
    state = new State(secureArgsList);
  }
@@ -2000,32 +1779,30 @@
   */
  public void resetConnectionArguments()
  {
    secureArgsList.hostNameArg.clearValues();
    secureArgsList.hostNameArg.setPresent(false);
    secureArgsList.portArg.clearValues();
    secureArgsList.portArg.setPresent(false);
    secureArgsList.getHostNameArg().clearValues();
    secureArgsList.getHostNameArg().setPresent(false);
    secureArgsList.getPortArg().clearValues();
    secureArgsList.getPortArg().setPresent(false);
    //  This is done to be able to call IntegerArgument.getIntValue()
    secureArgsList.portArg.addValue(secureArgsList.portArg.getDefaultValue());
    secureArgsList.bindDnArg.clearValues();
    secureArgsList.bindDnArg.setPresent(false);
    secureArgsList.bindPasswordArg.clearValues();
    secureArgsList.bindPasswordArg.setPresent(false);
    secureArgsList.bindPasswordFileArg.clearValues();
    secureArgsList.bindPasswordFileArg.getNameToValueMap().clear();
    secureArgsList.bindPasswordFileArg.setPresent(false);
    secureArgsList.getPortArg().addValue(secureArgsList.getPortArg().getDefaultValue());
    secureArgsList.getBindDnArg().clearValues();
    secureArgsList.getBindDnArg().setPresent(false);
    secureArgsList.getBindPasswordArg().clearValues();
    secureArgsList.getBindPasswordArg().setPresent(false);
    secureArgsList.getBindPasswordFileArg().clearValues();
    secureArgsList.getBindPasswordFileArg().getNameToValueMap().clear();
    secureArgsList.getBindPasswordFileArg().setPresent(false);
    state.bindPassword = null;
    secureArgsList.adminUidArg.clearValues();
    secureArgsList.adminUidArg.setPresent(false);
    secureArgsList.getAdminUidArg().clearValues();
    secureArgsList.getAdminUidArg().setPresent(false);
  }
  private void initializeTrustManager() throws ArgumentException
  private void initializeTrustAndKeyManagers() throws ArgumentException
  {
    // Get trust store info
    state.trustManager = getTrustManagerInternal();
    // Check if we need client side authentication
    state.keyManager = getKeyManagerInternal();
    state.trustManagerInitialized = true;
  }
@@ -2058,35 +1835,33 @@
   *
   * @return true if the local trust store has been added.
   */
  private boolean addLocalTrustStore()
  private boolean useLocalTrustStoreIfPossible()
  {
    try
    {
      // If remote host, return
      if (!InetAddress.getLocalHost().getHostName().equals(state.hostName)
          || secureArgsList.getAdminPortFromConfig() != portNumber)
      if (InetAddress.getLocalHost().getHostName().equals(state.hostName)
          && secureArgsList.getAdminPortFromConfig() == portNumber)
      {
        return false;
        final String trustStoreFileAbsolute = secureArgsList.getTruststoreFileFromConfig();
        if (trustStoreFileAbsolute != null)
        {
          secureArgsList.getTrustStorePathArg().addValue(trustStoreFileAbsolute);
          return true;
        }
      }
      // check if we are in a local instance. Already checked the host,
      // now check the port
      if (secureArgsList.getAdminPortFromConfig() != portNumber)
      {
        return false;
      }
      String truststoreFileAbsolute = secureArgsList.getTruststoreFileFromConfig();
      if (truststoreFileAbsolute != null)
      {
        secureArgsList.trustStorePathArg.addValue(truststoreFileAbsolute);
        return true;
      }
      return false;
    }
    catch (Exception ex)
    {
      // do nothing
      return false;
    }
    return false;
  }
  private void throwIfMenuResultNotSucceeded(final MenuResult<?> result)
  {
    if (!result.isSuccess())
    {
      throw new RuntimeException("Expected successful menu result, but got " + result);
    }
  }
}
opendj-server-legacy/src/messages/org/opends/messages/tool.properties
@@ -2706,3 +2706,13 @@
ERR_CONFIRMATION_TRIES_LIMIT_REACHED=Confirmation tries limit reached (%d)
REF_SHORT_DESC_UNINSTALL=remove OpenDJ directory server software
INFO_CERTIFICATE_EXCEPTION_CAUSE=Certificate exception cause: %s
ERROR_CERTIFICATE_PARSING_URL=Error parsing ldap url %s: %s
ERROR_CERTIFICATE_NULL_AUTH_TYPE=Null auth type for this certificate exception
ERROR_CERTIFICATE_NULL_CHAIN=Null chain for this certificate exception
ERROR_CERTIFICATE_NULL_HOST_NAME=Null host name for this certificate exception
ERR_RESOLVE_KEYSTORE_ALIASES=Unable to resolve keystore aliases: %s
ERR_TRUSTING_CERTIFICATE=Unable to trust the certificate because: %s
ERR_TRUSTING_CERTIFICATE_PERMANENTLY=Unable to trust the certificate permanently, \
 certificate will be trusted only for this session. Error details: %s