From 111c848e2d90d962a7f48d7b4121304247829473 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 05 Sep 2007 06:40:30 +0000
Subject: [PATCH] The following changes are targetted to fix a certain number of issues related to the setup command line:
---
opends/src/server/org/opends/server/tools/InstallDS.java | 2681 ++++++++++++++++++++++++++++++++---------------------------
1 files changed, 1,464 insertions(+), 1,217 deletions(-)
diff --git a/opends/src/server/org/opends/server/tools/InstallDS.java b/opends/src/server/org/opends/server/tools/InstallDS.java
index b9eb537..123d86a 100644
--- a/opends/src/server/org/opends/server/tools/InstallDS.java
+++ b/opends/src/server/org/opends/server/tools/InstallDS.java
@@ -24,1153 +24,1627 @@
*
* Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
+
package org.opends.server.tools;
-import org.opends.messages.Message;
+import static org.opends.messages.AdminToolMessages.*;
+import static org.opends.messages.QuickSetupMessages.*;
+import static org.opends.messages.ToolMessages.*;
-
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.KeyStoreException;
+import java.util.Collection;
import java.util.LinkedList;
-import java.util.Set;
+import java.util.logging.Logger;
+import org.opends.messages.Message;
+import org.opends.quicksetup.ApplicationException;
+import org.opends.quicksetup.CliApplicationHelper;
+import org.opends.quicksetup.Constants;
+import org.opends.quicksetup.CurrentInstallStatus;
+import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.QuickSetupLog;
+import org.opends.quicksetup.SecurityOptions;
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.UserDataException;
+import org.opends.quicksetup.event.ProgressUpdateEvent;
+import org.opends.quicksetup.event.ProgressUpdateListener;
+import org.opends.quicksetup.installer.NewSuffixOptions;
+import org.opends.quicksetup.installer.offline.OfflineInstaller;
+import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
+import org.opends.quicksetup.util.Utils;
import org.opends.server.core.DirectoryServer;
-import org.opends.server.extensions.ConfigFileHandler;
import org.opends.server.types.DN;
-import org.opends.server.types.ExistingFileBehavior;
-import org.opends.server.types.LDIFExportConfig;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.CertificateManager;
import org.opends.server.util.SetupUtils;
-import org.opends.server.util.LDIFWriter;
-import org.opends.server.util.PasswordReader;
import org.opends.server.util.args.ArgumentException;
-import org.opends.server.util.args.ArgumentParser;
-import org.opends.server.util.args.BooleanArgument;
-import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.args.IntegerArgument;
import org.opends.server.util.args.StringArgument;
-import static org.opends.messages.ToolMessages.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-import static org.opends.server.tools.ToolConstants.*;
-
-
-
/**
* This class provides a very simple mechanism for installing the OpenDS
* Directory Service. It performs the following tasks:
* <UL>
+ * <LI>Checks if the server is already installed and running</LI>
* <LI>Ask the user what base DN should be used for the data</LI>
* <LI>Ask the user whether to create the base entry, or to import LDIF</LI>
* <LI>Ask the user for the LDAP port and make sure it's available</LI>
* <LI>Ask the user for the default root DN and password</LI>
+ * <LI>Ask the user to enable SSL or not and for the type of certificate that
+ * the server must use</LI>
* <LI>Ask the user if they want to start the server when done installing</LI>
* </UL>
*/
-public class InstallDS
+public class InstallDS extends CliApplicationHelper
{
- /**
- * The fully-qualified name of this class.
- */
- private static final String CLASS_NAME = "org.opends.server.tools.InstallDS";
+ private PlainTextProgressMessageFormatter formatter =
+ new PlainTextProgressMessageFormatter();
+ /** Prefix for log files. */
+ static public final String LOG_FILE_PREFIX = "opends-setup-";
-
+ /** Suffix for log files. */
+ static public final String LOG_FILE_SUFFIX = ".log";
/**
- * Indicates whether we think we're running on a Windows system.
- */
- private static final boolean isWindows = SetupUtils.isWindows();
-
-
-
- /**
- * The version string for the server.
- */
- private static String versionString;
-
-
-
- /**
- * The name of the program used to launch this installation process.
- */
- private static String programName;
-
-
-
- /**
- * The value that indicates that only the base entry should be created.
- */
- private static final int POPULATE_TYPE_BASE_ONLY = 1;
-
-
-
- /**
- * The value that indicates that the database should be left empty.
- */
- private static final int POPULATE_TYPE_LEAVE_EMPTY = 2;
-
-
-
- /**
- * The value that indicates that data should be imported from an LDIF file.
- */
- private static final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
-
-
-
- /**
- * The value that indicates that the database should be populated with sample
- * data.
- */
- private static final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
-
-
-
- /**
- * Invokes the <CODE>installMain</CODE> method with the provided arguments.
+ * The enumeration containing the different return codes that the command-line
+ * can have.
*
- * @param args The command-line arguments to use for this program.
*/
- public static void main(String[] args)
+ enum ErrorReturnCode
{
- int exitCode = installMain(args);
- if (exitCode != 0)
+ /**
+ * Successful setup.
+ */
+ SUCCESSFUL(0),
+ /**
+ * We did no have an error but the setup was not executed (displayed
+ * version or usage).
+ */
+ SUCCESSFUL_NOP(0),
+ /**
+ * Unexpected error (potential bug).
+ */
+ ERROR_UNEXPECTED(1),
+ /**
+ * Cannot parse arguments or data provided by user is not valid.
+ */
+ ERROR_USER_DATA(2),
+ /**
+ * Error server already installed.
+ */
+ ERROR_SERVER_ALREADY_INSTALLED(3),
+ /**
+ * Error initializing server.
+ */
+ ERROR_INITIALIZING_SERVER(4);
+
+ private int returnCode;
+ private ErrorReturnCode(int returnCode)
{
- System.exit(filterExitCode(exitCode));
+ this.returnCode = returnCode;
}
+
+ /**
+ * Get the corresponding return code value.
+ *
+ * @return The corresponding return code value.
+ */
+ public int getReturnCode()
+ {
+ return returnCode;
+ }
+ };
+
+ /**
+ * The Logger.
+ */
+ static private final Logger LOG = Logger.getLogger(InstallDS.class.getName());
+
+ // The argument parser
+ private InstallDSArgumentParser argParser;
+
+ /**
+ * Constructor for the SetupCli object.
+ *
+ * @param out the print stream to use for standard output.
+ * @param err the print stream to use for standard error.
+ * @param in the input stream to use for standard input.
+ */
+ public InstallDS(PrintStream out, PrintStream err, InputStream in)
+ {
+ super(out, err, in);
}
+ /**
+ * The main method for the setup CLI tool.
+ *
+ * @param args the command-line arguments provided to this program.
+ */
+ public static void main(String[] args)
+ {
+ int retCode = mainCLI(args, true, System.out, System.err, System.in);
+
+ System.exit(retCode);
+ }
/**
- * Prompts the user for the necessary information, installs the OpenDS
- * software in the appropriate location, and gives it the desired
- * configuration.
+ * Parses the provided command-line arguments and uses that information to
+ * run the setup tool.
*
- * @param args The command-line arguments to use for this program.
+ * @param args the command-line arguments provided to this program.
*
- * @return A value of zero if the installation process was successful, or a
- * nonzero value if a problem occurred.
+ * @return The error code.
*/
- public static int installMain(String[] args)
- {
- // Construct the product version string and the setup filename.
- versionString = DirectoryServer.getVersionString();
- if (isWindows)
+ public static int mainCLI(String[] args)
+ {
+ return mainCLI(args, true, System.out, System.err, System.in);
+ }
+
+ /**
+ * Parses the provided command-line arguments and uses that information to
+ * run the setup tool.
+ *
+ * @param args The command-line arguments provided to this
+ * program.
+ * @param initializeServer Indicates whether to initialize the server.
+ * @param outStream The output stream to use for standard output, or
+ * <CODE>null</CODE> if standard output is not
+ * needed.
+ * @param errStream The output stream to use for standard error, or
+ * <CODE>null</CODE> if standard error is not
+ * needed.
+ * @param inStream The input stream to use for standard input.
+ * @return The error code.
+ */
+
+ public static int mainCLI(String[] args, boolean initializeServer,
+ OutputStream outStream, OutputStream errStream, InputStream inStream)
+ {
+ PrintStream out;
+ if (outStream == null)
{
- programName = "setup.bat";
+ out = NullOutputStream.printStream();
}
else
{
- programName = "setup";
+ out = new PrintStream(outStream);
}
+ System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
- // Create and initialize the argument parser for this program.
- Message toolDescription = INFO_INSTALLDS_TOOL_DESCRIPTION.get();
- ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
- false);
- BooleanArgument addBaseEntry;
- BooleanArgument cliMode;
- BooleanArgument testOnly;
- BooleanArgument showUsage;
- BooleanArgument quietInstall;
- BooleanArgument skipPortCheck;
- BooleanArgument enableWindowsService;
- FileBasedArgument rootPWFile;
- IntegerArgument ldapPort;
- IntegerArgument jmxPort;
- IntegerArgument sampleData;
- StringArgument baseDN;
- StringArgument configClass;
- StringArgument configFile;
- StringArgument importLDIF;
- StringArgument progName;
- StringArgument rootDN;
- StringArgument rootPWString;
+ PrintStream err;
+ if (errStream == null)
+ {
+ err = NullOutputStream.printStream();
+ }
+ else
+ {
+ err = new PrintStream(errStream);
+ }
+ try {
+ QuickSetupLog.initLogFileHandler(
+ File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX),
+ "org.opends.server.tools");
+ QuickSetupLog.disableConsoleLogging();
+ } catch (Throwable t) {
+ System.err.println("Unable to initialize log");
+ t.printStackTrace();
+ }
+
+ InstallDS install = new InstallDS(out, err, inStream);
+
+ return install.execute(args, initializeServer);
+ }
+
+ /**
+ * Parses the provided command-line arguments and uses that information to
+ * run the setup CLI.
+ *
+ * @param args the command-line arguments provided to this program.
+ * @param initializeServer Indicates whether to initialize the server.
+ *
+ * @return the return code (SUCCESSFUL, USER_DATA_ERROR or BUG.
+ */
+ public int execute(String[] args, boolean initializeServer)
+ {
+ argParser = new InstallDSArgumentParser(InstallDS.class.getName());
try
{
- testOnly = new BooleanArgument(
- "test", 't', "testOnly",
- INFO_INSTALLDS_DESCRIPTION_TESTONLY.get());
- testOnly.setHidden(true);
- argParser.addArgument(testOnly);
-
- progName = new StringArgument(
- "progname", 'P', "programName", false,
- false, true, "{programName}", programName,
- null, INFO_INSTALLDS_DESCRIPTION_PROGNAME.get());
- progName.setHidden(true);
- argParser.addArgument(progName);
-
- configFile = new StringArgument(
- "configfile", 'c', "configFile", false,
- false, true, "{configFile}", null, null,
- INFO_DESCRIPTION_CONFIG_FILE.get());
- configFile.setHidden(true);
- argParser.addArgument(configFile);
-
- configClass = new StringArgument(
- "configclass", OPTION_SHORT_CONFIG_CLASS,
- OPTION_LONG_CONFIG_CLASS, false,
- false, true, OPTION_VALUE_CONFIG_CLASS,
- ConfigFileHandler.class.getName(), null,
- INFO_DESCRIPTION_CONFIG_CLASS.get());
- configClass.setHidden(true);
- argParser.addArgument(configClass);
-
- // NOTE: This argument isn't actually used for anything, but it provides
- // consistency with the setup script, which does take a --cli option.
- cliMode = new BooleanArgument(
- "cli", null, OPTION_LONG_CLI,
- INFO_INSTALLDS_DESCRIPTION_CLI.get());
- argParser.addArgument(cliMode);
-
- quietInstall = new BooleanArgument(
- "quiet", OPTION_SHORT_QUIET,
- OPTION_LONG_QUIET,
- INFO_INSTALLDS_DESCRIPTION_SILENT.get());
- argParser.addArgument(quietInstall);
-
- baseDN = new StringArgument(
- "basedn", OPTION_SHORT_BASEDN,
- OPTION_LONG_BASEDN, false, true, true,
- OPTION_VALUE_BASEDN,
- "dc=example,dc=com", null,
- INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
- argParser.addArgument(baseDN);
-
- addBaseEntry = new BooleanArgument(
- "addbase", 'a', "addBaseEntry",
- INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
- argParser.addArgument(addBaseEntry);
-
- importLDIF = new StringArgument(
- "importldif", OPTION_SHORT_LDIF_FILE,
- OPTION_LONG_LDIF_FILE, false,
- true, true, OPTION_VALUE_LDIF_FILE,
- null, null,
- INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
- argParser.addArgument(importLDIF);
-
- sampleData = new IntegerArgument(
- "sampledata", 'd', "sampleData", false,
- false, true, "{numEntries}", 0, null,
- true, 0, false, 0,
- INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
- argParser.addArgument(sampleData);
-
- ldapPort = new IntegerArgument(
- "ldapport", OPTION_SHORT_PORT,
- "ldapPort", false, false,
- true, OPTION_VALUE_PORT, 389,
- null, true, 1, true, 65535,
- INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
- argParser.addArgument(ldapPort);
-
- jmxPort = new IntegerArgument(
- "jmxport", 'x', "jmxPort", false, false,
- true, "{jmxPort}",
- SetupUtils.getDefaultJMXPort(), null, true,
- 1, true, 65535,
- INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
- argParser.addArgument(jmxPort);
-
- skipPortCheck = new BooleanArgument(
- "skipportcheck", 'S', "skipPortCheck",
- INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
- argParser.addArgument(skipPortCheck);
-
- rootDN = new StringArgument(
- "rootdn",OPTION_SHORT_ROOT_USER_DN,
- OPTION_LONG_ROOT_USER_DN, false, true,
- true, OPTION_VALUE_ROOT_USER_DN,
- "cn=Directory Manager",
- null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
- argParser.addArgument(rootDN);
-
- rootPWString = new StringArgument(
- "rootpwstring", OPTION_SHORT_BINDPWD,
- "rootUserPassword",
- false, false, true,
- "{password}", null,
- null,
- INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
- argParser.addArgument(rootPWString);
-
- rootPWFile = new FileBasedArgument(
- "rootpwfile",
- OPTION_SHORT_BINDPWD_FILE,
- "rootUserPasswordFile", false, false,
- OPTION_VALUE_BINDPWD_FILE,
- null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
- argParser.addArgument(rootPWFile);
-
- enableWindowsService = new BooleanArgument(
- "enablewindowsservice", 'e',
- "enableWindowsService",
- INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
- if (SetupUtils.isWindows())
- {
- argParser.addArgument(enableWindowsService);
- }
-
- showUsage = new BooleanArgument("help", OPTION_SHORT_HELP,
- OPTION_LONG_HELP,
- INFO_INSTALLDS_DESCRIPTION_HELP.get());
- argParser.addArgument(showUsage);
- argParser.setUsageArgument(showUsage);
+ argParser.initializeArguments();
}
catch (ArgumentException ae)
{
- System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
- System.err.println(argParser.getUsage());
- return 1;
+ Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
+ printErrorMessage(message);
+ return ErrorReturnCode.ERROR_UNEXPECTED.getReturnCode();
}
-
- // Parse all of the configuration arguments.
+ // Validate user provided data
try
{
argParser.parseArguments(args);
}
catch (ArgumentException ae)
{
- System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
- System.err.println(argParser.getUsage());
- return 1;
+ Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
+ printErrorMessage(message);
+ printLineBreak();
+ printErrorMessage(argParser.getUsage());
+
+ return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
}
-
- // If either the showUsage or testOnly or version arguments were provided,
+ // If either the showUsage or testOnly or version arguments were provided,
// then we're done.
- if (argParser.usageOrVersionDisplayed() || testOnly.isPresent())
+ if (argParser.usageOrVersionDisplayed() ||
+ argParser.testOnlyArg.isPresent())
{
- return 0;
+ return ErrorReturnCode.SUCCESSFUL_NOP.getReturnCode();
}
try
{
- Set<Integer> ports = new HashSet<Integer>();
- if (ldapPort.isPresent())
- {
- ports.add(ldapPort.getIntValue());
- }
- if (jmxPort.isPresent())
- {
- if (ports.contains(jmxPort.getIntValue()))
- {
- Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
- String.valueOf(jmxPort.getIntValue()));
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- System.err.println(argParser.getUsage());
- return 1;
- }
- else
- {
- ports.add(jmxPort.getIntValue());
- }
- }
+ checkInstallStatus();
}
- catch (ArgumentException ae)
+ catch (InitializationException ie)
{
- Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ printErrorMessage(ie.getMessageObject());
+ return ErrorReturnCode.ERROR_SERVER_ALREADY_INSTALLED.getReturnCode();
}
- // Make sure that the user didn't provide conflicting arguments.
- if (addBaseEntry.isPresent())
+ if (initializeServer)
{
- if (importLDIF.isPresent())
+ try
{
- Message message = ERR_TOOL_CONFLICTING_ARGS.get(
- addBaseEntry.getLongIdentifier(),
- importLDIF.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ initializeDirectoryServer(argParser.configFileArg.getValue(),
+ argParser.configClassArg.getValue());
}
- else if (sampleData.isPresent())
+ catch (InitializationException ie)
{
- Message message = ERR_TOOL_CONFLICTING_ARGS.get(
- addBaseEntry.getLongIdentifier(),
- sampleData.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ printErrorMessage(ie.getMessageObject());
+ return ErrorReturnCode.ERROR_INITIALIZING_SERVER.getReturnCode();
}
}
- else if (importLDIF.isPresent() && sampleData.isPresent())
- {
- Message message = ERR_TOOL_CONFLICTING_ARGS.get(
- importLDIF.getLongIdentifier(),
- sampleData.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
+ UserData uData = new UserData();
- // Make sure the path to the configuration file was given.
- String configFileName;
- if (configFile.isPresent())
+ if (isInteractive())
{
- configFileName = configFile.getValue();
+ promptIfRequired(uData);
}
else
{
- Message message = ERR_INSTALLDS_NO_CONFIG_FILE.get(
- configFile.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ try
+ {
+ initializeUserDataWithParser(uData);
+ }
+ catch (UserDataException ude)
+ {
+ printErrorMessage(ude.getMessageObject());
+ return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
+ }
}
+ OfflineInstaller installer = new OfflineInstaller();
+ installer.setUserData(uData);
+ System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
+ installer.setProgressMessageFormatter(formatter);
+ installer.addProgressUpdateListener(
+ new ProgressUpdateListener() {
+ public void progressUpdate(ProgressUpdateEvent ev) {
+ if (ev.getNewLogs() != null)
+ {
+ printProgressMessage(ev.getNewLogs());
+ }
+ }
+ });
+ printProgressLineBreak();
- // Get the configuration handler class name.
- String configClassName = configClass.getValue();
+ installer.run();
+ ApplicationException ue = installer.getRunError();
- // If this isn't a quiet install, then print the version string.
- if (! quietInstall.isPresent())
+ String cmd;
+ // Use this instead a call to Installation to avoid to launch a new JVM
+ // just to retrieve a path.
+ String root = Utils.getInstallPathFromClasspath();
+ if (SetupUtils.isWindows())
{
- System.out.println(versionString);
- System.out.println();
-
- Message message = INFO_INSTALLDS_INITIALIZING.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
+ String binDir = Utils.getPath(root,
+ Installation.WINDOWS_BINARIES_PATH_RELATIVE);
+ cmd = Utils.getPath(binDir, Installation.WINDOWS_STATUSCLI_FILE_NAME);
}
+ else
+ {
+ String binDir = Utils.getPath(root,
+ Installation.UNIX_BINARIES_PATH_RELATIVE);
+ cmd = Utils.getPath(binDir, Installation.UNIX_STATUSCLI_FILE_NAME);
+ }
+ printProgressLineBreak();
+ printProgressLineBreak();
+ printProgressMessage(INFO_INSTALLDS_STATUS_COMMAND_LINE.get(cmd));
+ printProgressLineBreak();
+ if (ue != null)
+ {
+ return ue.getType().getReturnCode();
+ }
+ else
+ {
+ return ErrorReturnCode.SUCCESSFUL.getReturnCode();
+ }
+ }
+
+ /**
+ * Checks if the server is installed or not.
+ * @throws InitializationException if the server is already installed and
+ * configured or if the user did not accept to overwrite the existing
+ * databases.
+ */
+ private void checkInstallStatus() throws InitializationException
+ {
+ CurrentInstallStatus installStatus = new CurrentInstallStatus();
+ if (installStatus.canOverwriteCurrentInstall())
+ {
+ if (isInteractive())
+ {
+ printLine(installStatus.getInstallationMsg(), true);
+ if (!confirm(INFO_CLI_DO_YOU_WANT_TO_CONTINUE.get()))
+ {
+ throw new InitializationException(Message.EMPTY, null);
+ }
+ }
+ else
+ {
+ printWarningMessage(installStatus.getInstallationMsg());
+ }
+ }
+ else if (installStatus.isInstalled())
+ {
+ throw new InitializationException(installStatus.getInstallationMsg(),
+ null);
+ }
+ }
+
+ /**
+ * Initialize the directory server to be able to perform the operations
+ * required during the installation.
+ * @param configFile the configuration file to be used to initialize the
+ * server.
+ * @param configClass the configuration class to be used to initialize the
+ * server.
+ * @throws InitializationException if there was an error during
+ * initialization.
+ */
+ private void initializeDirectoryServer(String configFile, String configClass)
+ throws InitializationException
+ {
+ printProgressLineBreak();
+ printProgressMessage(DirectoryServer.getVersionString());
+ printProgressLineBreak();
+ printProgressMessage(INFO_INSTALLDS_INITIALIZING.get());
+ printProgressLineBreak();
// Perform a base-level initialization that will be required to get
// minimal functionality like DN parsing to work.
DirectoryServer directoryServer = DirectoryServer.getInstance();
- directoryServer.bootstrapClient();
+ DirectoryServer.bootstrapClient();
try
{
- directoryServer.initializeJMX();
+ DirectoryServer.initializeJMX();
}
- catch (Exception e)
+ catch (Throwable t)
{
Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_JMX.get(
- String.valueOf(configFile.getValue()),
- e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ String.valueOf(configFile), t.getMessage());
+ throw new InitializationException(message, t);
}
try
{
- directoryServer.initializeConfiguration(configClass.getValue(),
- configFile.getValue());
+ directoryServer.initializeConfiguration(configClass, configFile);
}
- catch (Exception e)
+ catch (Throwable t)
{
Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_CONFIG.get(
- String.valueOf(configFile.getValue()),
- e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ configFile, t.getMessage());
+ throw new InitializationException(message, t);
}
try
{
directoryServer.initializeSchema();
}
- catch (Exception e)
+ catch (Throwable t)
{
Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_SCHEMA.get(
- String.valueOf(configFile.getValue()),
- e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ configFile, t.getMessage());
+ throw new InitializationException(message, t);
}
+ }
+ /**
+ * {@inheritDoc}
+ */
+ protected boolean isQuiet()
+ {
+ return argParser.quietArg.isPresent();
+ }
- // Determine the LDAP port number.
- int ldapPortNumber;
- if (quietInstall.isPresent() || ldapPort.isPresent())
+ /**
+ * {@inheritDoc}
+ */
+ protected boolean isInteractive()
+ {
+ return !argParser.noPromptArg.isPresent();
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line. It assumes that it is being called in no
+ * prompt mode.
+ * @param uData the UserData object.
+ * @throws UserDataException if something went wrong checking the data.
+ */
+ private void initializeUserDataWithParser(UserData uData)
+ throws UserDataException
+ {
+ LinkedList<Message> errorMessages = new LinkedList<Message>();
+ uData.setConfigurationClassName(argParser.configClassArg.getValue());
+ uData.setConfigurationFile(argParser.configFileArg.getValue());
+ uData.setQuiet(isQuiet());
+ // Check the validity of the directory manager DNs
+ String dmDN = argParser.directoryManagerDNArg.getValue();
+
+ try
+ {
+ DN.decode(dmDN);
+ }
+ catch (Exception e)
+ {
+ Message message =
+ ERR_INSTALLDS_CANNOT_PARSE_DN.get(dmDN, e.getMessage());
+ errorMessages.add(message);
+ }
+ uData.setDirectoryManagerDn(dmDN);
+
+ uData.setDirectoryManagerPwd(argParser.getDirectoryManagerPassword());
+
+ // Check the validity of the base DNs
+ LinkedList<String> baseDNs = argParser.baseDNArg.getValues();
+ if (baseDNs.isEmpty())
+ {
+ baseDNs.add(argParser.baseDNArg.getDefaultValue());
+ }
+ for (String baseDN : baseDNs)
{
try
{
- ldapPortNumber = ldapPort.getIntValue();
-
- if (! skipPortCheck.isPresent())
- {
- // Check if the port can be used.
- if (!SetupUtils.canUseAsPort(ldapPortNumber))
- {
- Message message;
- if (SetupUtils.isPriviledgedPort(ldapPortNumber))
- {
-
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
- ldapPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
-
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- return 1;
- }
- }
- }
- catch (ArgumentException ae)
- {
- System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
- return 1;
- }
- }
- else
- {
- while (true)
- {
- Message message = INFO_INSTALLDS_PROMPT_LDAPPORT.get();
- ldapPortNumber = promptForInteger(message, 389, 1, 65535);
-
- if (skipPortCheck.isPresent())
- {
- break;
- }
- else
- {
- // Check if the port can be used.
- if (SetupUtils.canUseAsPort(ldapPortNumber))
- {
- break;
- }
- else
- {
- if (SetupUtils.isPriviledgedPort(ldapPortNumber))
- {
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
- ldapPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- }
- }
- }
- }
-
-// Determine the JMX port number.
- int jmxPortNumber;
- if (quietInstall.isPresent() || jmxPort.isPresent())
- {
- try
- {
- jmxPortNumber = jmxPort.getIntValue();
-
- if (! skipPortCheck.isPresent())
- {
- // Check if the port can be used.
- if (!SetupUtils.canUseAsPort(jmxPortNumber))
- {
- Message message;
- if (SetupUtils.isPriviledgedPort(jmxPortNumber))
- {
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
- jmxPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- return 1;
- }
- }
- }
- catch (ArgumentException ae)
- {
- System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
- return 1;
- }
- }
- else
- {
- /* Do not ask for the JMX port if the user did not provide it.*/
- jmxPortNumber = -1;
- /*
- while (true)
- {
- Message message = INFO_INSTALLDS_PROMPT_JMXPORT.get();
- jmxPortNumber = promptForInteger(message,
- SetupUtils.getDefaultJMXPort(), 1, 65535);
-
- if (skipPortCheck.isPresent())
- {
- break;
- }
- else
- {
- // Check if the port can be used.
- if (SetupUtils.canUseAsPort(jmxPortNumber))
- {
- break;
- }
- else
- {
- if (SetupUtils.isPriviledgedPort(jmxPortNumber))
- {
-
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
- jmxPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- }
- }
- }
- */
- }
-
-
- // Determine the initial root user DN.
- LinkedList<DN> rootDNs;
- if (rootDN.isPresent())
- {
- rootDNs = new LinkedList<DN>();
- for (String s : rootDN.getValues())
- {
- try
- {
- rootDNs.add(DN.decode(s));
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
- s, e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
- }
- else if (quietInstall.isPresent())
- {
- rootDNs = new LinkedList<DN>();
- try
- {
- rootDNs.add(DN.decode(rootDN.getDefaultValue()));
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
- rootDN.getDefaultValue(),
- e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
- else
- {
- Message message = INFO_INSTALLDS_PROMPT_ROOT_DN.get();
- rootDNs = new LinkedList<DN>();
- rootDNs.add(promptForDN(message, rootDN.getDefaultValue()));
- }
-
-
- // Determine the initial root user password.
- String rootPassword;
- if (rootPWString.isPresent())
- {
- rootPassword = rootPWString.getValue();
-
- if (rootPWFile.isPresent())
- {
- Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
- rootPWString.getLongIdentifier(),
- rootPWFile.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
- else if (rootPWFile.isPresent())
- {
- rootPassword = rootPWFile.getValue();
- }
- else if (quietInstall.isPresent())
- {
- Message message = ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
- rootPWString.getLongIdentifier(),
- rootPWFile.getLongIdentifier());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- else
- {
- Message initialPrompt = INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get();
-
- Message confirmPrompt = INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get();
-
- rootPassword =
- new String(promptForPassword(initialPrompt, confirmPrompt));
- }
-
-
- // Determine the directory base DN.
- LinkedList<DN> baseDNs;
- if (baseDN.isPresent())
- {
- baseDNs = new LinkedList<DN>();
- for (String s : baseDN.getValues())
- {
- try
- {
- baseDNs.add(DN.decode(s));
- }
- catch (Exception e)
- {
-
- Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
- s, e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
- }
- else if (quietInstall.isPresent())
- {
- try
- {
- baseDNs = new LinkedList<DN>();
- baseDNs.add(DN.decode(baseDN.getDefaultValue()));
+ DN.decode(baseDN);
}
catch (Exception e)
{
Message message =
- ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN.getDefaultValue(),
- e.getMessage());
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
+ ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN, e.getMessage());
+ errorMessages.add(message);
}
}
- else
- {
- Message message = INFO_INSTALLDS_PROMPT_BASEDN.get();
- baseDNs = new LinkedList<DN>();
- baseDNs.add(promptForDN(message, baseDN.getDefaultValue()));
- }
-
-
- // Determine how to populate the database.
- int populateType = POPULATE_TYPE_LEAVE_EMPTY;
- int numUsers = -1;
- LinkedList<String> ldifFiles = null;
- if (addBaseEntry.isPresent())
+ try
{
- populateType = POPULATE_TYPE_BASE_ONLY;
- }
- else if (importLDIF.isPresent())
- {
- ldifFiles = importLDIF.getValues();
- populateType = POPULATE_TYPE_IMPORT_FROM_LDIF;
- }
- else if (sampleData.isPresent())
- {
- try
+ int ldapPort = argParser.ldapPortArg.getIntValue();
+ uData.setServerPort(ldapPort);
+ if (!argParser.skipPortCheckArg.isPresent())
{
- numUsers = sampleData.getIntValue();
- populateType = POPULATE_TYPE_GENERATE_SAMPLE_DATA;
- }
- catch (Exception e)
- {
- // This should never happen.
- e.printStackTrace();
- return 1;
- }
- }
- else if (quietInstall.isPresent())
- {
- populateType = POPULATE_TYPE_LEAVE_EMPTY;
- }
- else
- {
- System.out.println(wrapText(
- INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(),
- MAX_LINE_WIDTH));
-
- System.out.println(wrapText("1. " +
- INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(),
- MAX_LINE_WIDTH));
-
- System.out.println(wrapText("2. " +
- INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(),
- MAX_LINE_WIDTH));
-
- System.out.println(wrapText("3. " +
- INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(),
- MAX_LINE_WIDTH));
-
- System.out.println(wrapText("4. " +
- INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(),
- MAX_LINE_WIDTH));
-
- populateType = promptForInteger(
- INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(), 1, 1, 4);
- System.out.println();
-
- if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
- {
- ldifFiles = new LinkedList<String>();
- while (true)
+ // Check if the port can be used.
+ if (!SetupUtils.canUseAsPort(ldapPort))
{
- Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
- String path = promptForString(message, "");
- if (new File(path).exists())
+ Message message;
+ if (SetupUtils.isPriviledgedPort(ldapPort))
{
- ldifFiles.add(path);
- System.out.println();
- break;
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+ ldapPort);
}
else
{
-
- message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- System.err.println();
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPort);
+ }
+ errorMessages.add(message);
+ }
+ }
+ if (argParser.jmxPortArg.isPresent())
+ {
+ int jmxPort = argParser.jmxPortArg.getIntValue();
+ uData.setServerPort(jmxPort);
+ // Check if the port can be used.
+ if (!argParser.skipPortCheckArg.isPresent())
+ {
+ if (!SetupUtils.canUseAsPort(jmxPort))
+ {
+ Message message;
+ if (SetupUtils.isPriviledgedPort(jmxPort))
+ {
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+ jmxPort);
+ }
+ else
+ {
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPort);
+ }
+ errorMessages.add(message);
}
}
}
+ }
+ catch (ArgumentException ae)
+ {
+ errorMessages.add(ae.getMessageObject());
+ }
+
+
+
+ NewSuffixOptions dataOptions;
+ if (argParser.importLDIFArg.isPresent())
+ {
+ // Check that the files exist
+ LinkedList<String> nonExistingFiles = new LinkedList<String>();
+ for (String file : argParser.importLDIFArg.getValues())
+ {
+ if (!Utils.fileExists(file))
+ {
+ nonExistingFiles.add(file);
+ }
+ }
+ if (nonExistingFiles.size() > 0)
+ {
+ errorMessages.add(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
+ Utils.getStringFromCollection(nonExistingFiles, ", ")));
+ }
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE, baseDNs,
+ argParser.importLDIFArg.getValues());
+ }
+ else if (argParser.addBaseEntryArg.isPresent())
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
+ }
+ else if (argParser.sampleDataArg.isPresent())
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, baseDNs,
+ new Integer(argParser.sampleDataArg.getValue()));
+ }
+ else
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
+ }
+ uData.setNewSuffixOptions(dataOptions);
+
+ // Check that the security data provided is valid.
+ String certNickname = argParser.certNicknameArg.getValue();
+ String pwd = argParser.getKeyStorePassword();
+ boolean enableSSL = argParser.ldapsPortArg.isPresent();
+ boolean enableStartTLS = argParser.enableStartTLSArg.isPresent();
+ int ldapsPort = -1;
+
+ try
+ {
+ ldapsPort = enableSSL ? argParser.ldapsPortArg.getIntValue() : -1;
+ }
+ catch (ArgumentException ae)
+ {
+ errorMessages.add(ae.getMessageObject());
+ }
+ if (enableSSL)
+ {
+ if (!argParser.skipPortCheckArg.isPresent())
+ {
+ if (!SetupUtils.canUseAsPort(ldapsPort))
+ {
+ if (SetupUtils.isPriviledgedPort(ldapsPort))
+ {
+ errorMessages.add(
+ ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(ldapsPort));
+ }
+ else
+ {
+ errorMessages.add(ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapsPort));
+ }
+ }
+ }
+ }
+ SecurityOptions securityOptions;
+ LinkedList<String> keystoreAliases = new LinkedList<String>();
+ if (argParser.generateSelfSignedCertificateArg.isPresent())
+ {
+ securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (argParser.useJavaKeyStoreArg.isPresent())
+ {
+ String path = argParser.useJavaKeyStoreArg.getValue();
+ checkCertificateInKeystore(SecurityOptions.CertificateType.JKS, path, pwd,
+ certNickname, errorMessages, keystoreAliases);
+ securityOptions = SecurityOptions.createJKSCertificateOptions(
+ path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ }
+ else if (argParser.usePkcs12Arg.isPresent())
+ {
+ String path = argParser.usePkcs12Arg.getValue();
+ checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS12, path,
+ pwd, certNickname, errorMessages, keystoreAliases);
+ securityOptions = SecurityOptions.createPKCS12CertificateOptions(
+ path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ }
+ else if (argParser.usePkcs11Arg.isPresent())
+ {
+ checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS11, null,
+ pwd, certNickname, errorMessages, keystoreAliases);
+ securityOptions = SecurityOptions.createPKCS11CertificateOptions(
+ pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ }
+ else
+ {
+ securityOptions = SecurityOptions.createNoCertificateOptions();
+ }
+ uData.setSecurityOptions(securityOptions);
+
+ uData.setEnableWindowsService(
+ argParser.enableWindowsServiceArg.isPresent());
+ uData.setStartServer(!argParser.doNotStartArg.isPresent());
+
+
+ if (errorMessages.size() > 0)
+ {
+ throw new UserDataException(null,
+ Utils.getMessageFromCollection(errorMessages,
+ formatter.getLineBreak().toString()));
+ }
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line. If the user did not provide explicitly some
+ * data or if the provided data is not valid, it prompts the user to provide
+ * it.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequired(UserData uData)
+ {
+ uData.setConfigurationClassName(argParser.configClassArg.getValue());
+ uData.setConfigurationFile(argParser.configFileArg.getValue());
+ uData.setQuiet(isQuiet());
+
+ promptIfRequiredForDirectoryManager(uData);
+ promptIfRequiredForPortData(uData);
+ promptIfRequiredForImportData(uData);
+ promptIfRequiredForSecurityData(uData);
+ promptIfRequiredForWindowsService(uData);
+ promptIfRequiredForStartServer(uData);
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the Directory Manager parameters.
+ * If the user did not provide explicitly some data or if the provided data is
+ * not valid, it prompts the user to provide it.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequiredForDirectoryManager(UserData uData)
+ {
+ LinkedList<String> dns = promptIfRequiredForDNs(
+ argParser.directoryManagerDNArg, INFO_INSTALLDS_PROMPT_ROOT_DN.get(),
+ true);
+ uData.setDirectoryManagerDn(dns.getFirst());
+
+ String pwd = argParser.getDirectoryManagerPassword();
+ while (pwd == null)
+ {
+ printLineBreak();
+ String pwd1 = null;
+ // Prompt for password and confirm.
+ while (pwd1 == null)
+ {
+ pwd1 = promptForPassword(INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get());
+ if ("".equals(pwd1))
+ {
+ pwd1 = null;
+ printLineBreak();
+ printErrorMessage(INFO_EMPTY_PWD.get());
+ }
+ }
+ String pwd2 =
+ promptForPassword(INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get());
+
+ if (pwd1.equals(pwd2))
+ {
+ pwd = pwd1;
+ }
+ else
+ {
+ printLineBreak();
+ printErrorMessage(ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get());
+ }
+ }
+ uData.setDirectoryManagerPwd(pwd);
+ }
+
+ /**
+ * This method returns a list of DNs. It checks that the provided list of
+ * actually contain some values. If no valid values are found it prompts
+ * the user to provide a valid DN.
+ * @param arg the Argument that the user provided to specify the DNs.
+ * @param promptMsg the prompt message to be displayed.
+ * @param includeLineBreak whether to include a line break before the first
+ * prompt or not.
+ * @return a list of valid DNs.
+ */
+ private LinkedList<String> promptIfRequiredForDNs(StringArgument arg,
+ Message promptMsg, boolean includeLineBreak)
+ {
+ LinkedList<String> dns = new LinkedList<String>();
+
+ boolean usedProvided = false;
+ boolean firstPrompt = true;
+ while (dns.isEmpty())
+ {
+ boolean prompted = false;
+ if (usedProvided || !arg.isPresent())
+ {
+ if (firstPrompt && includeLineBreak)
+ {
+ printLineBreak();
+ }
+ String dn = promptForString(promptMsg, arg.getDefaultValue());
+ firstPrompt = false;
+ dns.add(dn);
+ prompted = true;
+ }
+ else
+ {
+ dns.addAll(arg.getValues());
+ }
+ LinkedList<String> toRemove = new LinkedList<String>();
+ for (String dn : dns)
+ {
+ try
+ {
+ DN.decode(dn);
+ }
+ catch (Exception e)
+ {
+ toRemove.add(dn);
+ Message message = prompted ? ERR_INSTALLDS_INVALID_DN_RESPONSE.get() :
+ ERR_INSTALLDS_CANNOT_PARSE_DN.get(dn, e.getMessage());
+ printErrorMessage(message);
+ }
+ }
+ if (toRemove.size() > 0)
+ {
+ printLineBreak();
+ }
+ dns.removeAll(toRemove);
+ }
+ return dns;
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the LDAP and JMX port parameters.
+ * If the user did not provide explicitly some data or if the provided data is
+ * not valid, it prompts the user to provide it.
+ * Note: this method does not update nor check the LDAPS port.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequiredForPortData(UserData uData)
+ {
+ LinkedList<Integer> usedPorts = new LinkedList<Integer>();
+ // Determine the LDAP port number.
+ int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
+ INFO_INSTALLDS_PROMPT_LDAPPORT.get(), usedPorts, true);
+ uData.setServerPort(ldapPort);
+ usedPorts.add(ldapPort);
+ if (argParser.jmxPortArg.isPresent())
+ {
+ int jmxPort = promptIfRequiredForPortData(argParser.jmxPortArg,
+ INFO_INSTALLDS_PROMPT_JMXPORT.get(), usedPorts, true);
+ uData.setServerJMXPort(jmxPort);
+ }
+ else
+ {
+ uData.setServerJMXPort(-1);
+ }
+ }
+
+ /**
+ * This method returns a valid port value. It checks that the provided
+ * argument contains a valid port. If a valid port is not found it prompts
+ * the user to provide a valid port.
+ * @param arg the Argument that the user provided to specify the port.
+ * @param promptMsg the prompt message to be displayed.
+ * @param usedPorts the list of ports the user provided before for other
+ * connection handlers.
+ * @param includeLineBreak whether to include a line break before the first
+ * prompt or not.
+ * @return a valid port number.
+ */
+ private int promptIfRequiredForPortData(IntegerArgument portArg,
+ Message promptMsg, Collection<Integer> usedPorts,
+ boolean includeLineBreak)
+ {
+ int portNumber = -1;
+ boolean usedProvided = false;
+ boolean firstPrompt = true;
+ while (portNumber == -1)
+ {
+ try
+ {
+ boolean prompted = false;
+ if (usedProvided || !portArg.isPresent())
+ {
+ int defaultValue = -1;
+ if (portArg.getDefaultValue() != null)
+ {
+ defaultValue = Integer.parseInt(portArg.getDefaultValue());
+ }
+ if (firstPrompt && includeLineBreak)
+ {
+ printLineBreak();
+ }
+ portNumber = promptForPort(promptMsg, defaultValue);
+ prompted = true;
+ firstPrompt = false;
+ }
+ else
+ {
+ portNumber = portArg.getIntValue();
+ usedProvided = true;
+ }
+
+ if (!argParser.skipPortCheckArg.isPresent())
+ {
+ // Check if the port can be used.
+ if (!SetupUtils.canUseAsPort(portNumber))
+ {
+ Message message;
+ if (SetupUtils.isPriviledgedPort(portNumber))
+ {
+ if (prompted || includeLineBreak)
+ {
+ printLineBreak();
+ }
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+ portNumber);
+ printErrorMessage(message);
+ portNumber = -1;
+ }
+ else
+ {
+ if (prompted || includeLineBreak)
+ {
+ printLineBreak();
+ }
+ message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(portNumber);
+ printErrorMessage(message);
+ printLineBreak();
+ portNumber = -1;
+ }
+ }
+ }
+ if (portNumber != -1)
+ {
+ if (usedPorts.contains(portNumber))
+ {
+ Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
+ String.valueOf(portNumber));
+ printErrorMessage(message);
+ printLineBreak();
+ portNumber = -1;
+ }
+ }
+ }
+ catch (ArgumentException ae)
+ {
+ printErrorMessage(ae.getMessage());
+ }
+ }
+ return portNumber;
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the base DN and data import parameters.
+ * If the user did not provide explicitly some data or if the provided data is
+ * not valid, it prompts the user to provide it.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequiredForImportData(UserData uData)
+ {
+ // Check the validity of the base DNs
+ LinkedList<String> baseDNs = promptIfRequiredForDNs(
+ argParser.baseDNArg, INFO_INSTALLDS_PROMPT_BASEDN.get(), true);
+
+ NewSuffixOptions dataOptions;
+ if (argParser.importLDIFArg.isPresent())
+ {
+ // Check that the files exist
+ LinkedList<String> nonExistingFiles = new LinkedList<String>();
+ LinkedList<String> importLDIFFiles = new LinkedList<String>();
+ for (String file : argParser.importLDIFArg.getValues())
+ {
+ if (!Utils.fileExists(file))
+ {
+ nonExistingFiles.add(file);
+ }
+ else
+ {
+ importLDIFFiles.add(file);
+ }
+ }
+ if (nonExistingFiles.size() > 0)
+ {
+ printLineBreak();
+ printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
+ Utils.getStringFromCollection(nonExistingFiles, ", ")));
+ }
+ while (importLDIFFiles.isEmpty())
+ {
+ printLineBreak();
+ String path = promptForString(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
+ null);
+ if (!Utils.fileExists(path))
+ {
+ printLineBreak();
+ printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path));
+ }
+ else
+ {
+ importLDIFFiles.add(path);
+ }
+ }
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
+ baseDNs, importLDIFFiles);
+ }
+ else if (argParser.addBaseEntryArg.isPresent())
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.CREATE_BASE_ENTRY,
+ baseDNs);
+ }
+ else if (argParser.sampleDataArg.isPresent())
+ {
+ int numUsers;
+ try
+ {
+ numUsers = argParser.sampleDataArg.getIntValue();
+ }
+ catch (ArgumentException ae)
+ {
+ printLineBreak();
+ printErrorMessage(ae.getMessageObject());
+ Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
+ numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
+ }
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
+ baseDNs, numUsers);
+ }
+ else
+ {
+ final int POPULATE_TYPE_BASE_ONLY = 1;
+ final int POPULATE_TYPE_LEAVE_EMPTY = 2;
+ final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
+ final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
+ Message[] options = new Message[] {
+ Message.raw(String.valueOf(POPULATE_TYPE_BASE_ONLY)),
+ Message.raw(String.valueOf(POPULATE_TYPE_LEAVE_EMPTY)),
+ Message.raw(String.valueOf(POPULATE_TYPE_IMPORT_FROM_LDIF)),
+ Message.raw(String.valueOf(POPULATE_TYPE_GENERATE_SAMPLE_DATA))
+ };
+ printLineBreak();
+ printLine(INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(), true);
+ printLine(INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(), true);
+ printLine(INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(), true);
+ printLine(INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(), true);
+ printLine(INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(), true);
+
+
+ Message answer = promptConfirm(
+ INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(),
+ options[0], options);
+ int populateType = new Integer(answer.toString());
+
+ if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
+ {
+ LinkedList<String> importLDIFFiles = new LinkedList<String>();
+ while (importLDIFFiles.isEmpty())
+ {
+ Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
+ printLineBreak();
+ String path = promptForString(message, null);
+ if (Utils.fileExists(path))
+ {
+ importLDIFFiles.add(path);
+ }
+ else
+ {
+ message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
+ printLineBreak();
+ printErrorMessage(message);
+ }
+ }
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
+ baseDNs, importLDIFFiles);
+ }
else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
{
Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
- numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
- System.out.println();
+ int numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
+
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
+ baseDNs, numUsers);
+ }
+ else if (populateType == POPULATE_TYPE_LEAVE_EMPTY)
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
+ }
+ else if (populateType == POPULATE_TYPE_BASE_ONLY)
+ {
+ dataOptions = new NewSuffixOptions(
+ NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
+ }
+ else
+ {
+ throw new IllegalStateException("Unexpected populateType: "+
+ populateType);
}
}
+ uData.setNewSuffixOptions(dataOptions);
+ }
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the security parameters.
+ * If the user did not provide explicitly some data or if the provided data is
+ * not valid, it prompts the user to provide it.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequiredForSecurityData(UserData uData)
+ {
+ // Check that the security data provided is valid.
+ boolean enableSSL = false;
+ boolean enableStartTLS = false;
+ int ldapsPort = -1;
+
+ LinkedList<Integer> usedPorts = new LinkedList<Integer>();
+ usedPorts.add(uData.getServerPort());
+ if (uData.getServerJMXPort() != -1)
+ {
+ usedPorts.add(uData.getServerJMXPort());
+ }
+
+ // Ask to enable SSL
+ ldapsPort = -1;
+ if (!argParser.ldapsPortArg.isPresent())
+ {
+ printLineBreak();
+ enableSSL = confirm(INFO_INSTALLDS_PROMPT_ENABLE_SSL.get(), false);
+ if (enableSSL)
+ {
+ ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
+ INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, false);
+ }
+ }
+ else
+ {
+ ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
+ INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, true);
+ enableSSL = true;
+ }
+
+ // Ask to enable Start TLS
+ if (!argParser.enableStartTLSArg.isPresent())
+ {
+ printLineBreak();
+ enableStartTLS = confirm(INFO_INSTALLDS_ENABLE_STARTTLS.get(),
+ argParser.enableStartTLSArg.isPresent());
+ }
+ else
+ {
+ enableStartTLS = true;
+ }
+
+ SecurityOptions securityOptions;
+ if (argParser.generateSelfSignedCertificateArg.isPresent())
+ {
+ securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (argParser.useJavaKeyStoreArg.isPresent())
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (argParser.usePkcs12Arg.isPresent())
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS12,
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (argParser.usePkcs11Arg.isPresent())
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS11,
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else
+ {
+ if (!enableSSL && !enableStartTLS)
+ {
+ // If the user did not want to enable SSL or start TLS do not ask
+ // to create a certificate.
+ securityOptions = SecurityOptions.createNoCertificateOptions();
+ }
+ else
+ {
+ final int SELF_SIGNED = 1;
+ final int JKS = 2;
+ final int PKCS12 = 3;
+ final int PKCS11 = 4;
+ Message[] options = new Message[] {
+ Message.raw(String.valueOf(SELF_SIGNED)),
+ Message.raw(String.valueOf(JKS)),
+ Message.raw(String.valueOf(PKCS12)),
+ Message.raw(String.valueOf(PKCS11))
+ };
+ printLineBreak();
+ printLine(INFO_INSTALLDS_HEADER_CERT_TYPE.get(), true);
+ printLine(INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED.get(), true);
+ printLine(INFO_INSTALLDS_CERT_OPTION_JKS.get(), true);
+ printLine(INFO_INSTALLDS_CERT_OPTION_PKCS12.get(), true);
+ printLine(INFO_INSTALLDS_CERT_OPTION_PKCS11.get(), true);
+
+ Message answer = promptConfirm(
+ INFO_INSTALLDS_PROMPT_CERT_TYPE_CHOICE.get(),
+ options[0], options);
+ int certType = new Integer(answer.toString());
+
+ if (certType == SELF_SIGNED)
+ {
+ securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (certType == JKS)
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
+ enableSSL, enableStartTLS, ldapsPort);
+ }
+ else if (certType == PKCS12)
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(
+ SecurityOptions.CertificateType.PKCS12, enableSSL,
+ enableStartTLS, ldapsPort);
+ }
+ else if (certType == PKCS11)
+ {
+ securityOptions =
+ createSecurityOptionsPrompting(
+ SecurityOptions.CertificateType.PKCS11, enableSSL,
+ enableStartTLS, ldapsPort);
+ }
+ else
+ {
+ throw new IllegalStateException("Unexpected cert type: "+ certType);
+ }
+ }
+ }
+ uData.setSecurityOptions(securityOptions);
+ }
+
+ /**
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the Windows Service parameters.
+ * If the user did not provide explicitly the data, it prompts the user to
+ * provide it.
+ * @param uData the UserData object to be updated.
+ */
+ private void promptIfRequiredForWindowsService(UserData uData)
+ {
boolean enableService = false;
// If we are in Windows ask if the server must run as a windows service.
if (SetupUtils.isWindows())
{
- if (quietInstall.isPresent())
- {
- enableService = enableWindowsService.isPresent();
- }
- else if (enableWindowsService.isPresent())
+ if (argParser.enableWindowsServiceArg.isPresent())
{
enableService = true;
}
else
{
+ printLineBreak();
Message message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
- enableService = promptForBoolean(message, Boolean.TRUE);
+ enableService = confirm(message, false);
}
}
-
- // At this point, we should be able to invoke the ConfigureDS utility to
- // apply the requested configuration.
- ArrayList<String> argList = new ArrayList<String>();
- argList.add("-C");
- argList.add(configClassName);
- argList.add("-c");
- argList.add(configFileName);
- argList.add("-p");
- argList.add(String.valueOf(ldapPortNumber));
- if (jmxPortNumber != -1)
- {
- argList.add("-x");
- argList.add(String.valueOf(jmxPortNumber));
- }
-
- for (DN dn : baseDNs)
- {
- argList.add("-b");
- argList.add(dn.toString());
- }
-
- for (DN dn : rootDNs)
- {
- argList.add("-D");
- argList.add(dn.toString());
- }
-
- argList.add("-w");
- argList.add(rootPassword);
-
- String[] configureDSArguments = new String[argList.size()];
- argList.toArray(configureDSArguments);
-
- if (! quietInstall.isPresent())
- {
- System.out.println();
-
- Message message = INFO_INSTALLDS_STATUS_CONFIGURING_DS.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- }
-
- int returnValue = ConfigureDS.configMain(configureDSArguments);
- if (returnValue != 0)
- {
- return returnValue;
- }
-
-
- // If we need to create a base LDIF file or a template file, then do so now.
- if (populateType == POPULATE_TYPE_BASE_ONLY)
- {
- // Create a temporary LDIF file that will hold the entry to add.
- if (! quietInstall.isPresent())
- {
- Message message = INFO_INSTALLDS_STATUS_CREATING_BASE_LDIF.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- }
-
- try
- {
- File ldifFile = File.createTempFile("opends-base-entry", ".ldif");
- String ldifFilePath = ldifFile.getAbsolutePath();
- ldifFile.deleteOnExit();
-
- LDIFExportConfig exportConfig =
- new LDIFExportConfig(ldifFilePath, ExistingFileBehavior.OVERWRITE);
- LDIFWriter writer = new LDIFWriter(exportConfig);
-
- for (DN dn : baseDNs)
- {
- writer.writeEntry(createEntry(dn));
- }
-
- writer.close();
-
- if (ldifFiles == null)
- {
- ldifFiles = new LinkedList<String>();
- }
- ldifFiles.add(ldifFilePath);
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_CANNOT_CREATE_BASE_ENTRY_LDIF.get(
- String.valueOf(e));
-
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
- else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
- {
- try
- {
- File templateFile = SetupUtils.createTemplateFile(
- baseDNs.getFirst().toString(), numUsers);
- if (ldifFiles == null)
- {
- ldifFiles = new LinkedList<String>();
- }
- ldifFiles.add(templateFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_CANNOT_CREATE_TEMPLATE_FILE.get(
- String.valueOf(e));
-
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- return 1;
- }
- }
-
- if ((ldifFiles != null) && (! ldifFiles.isEmpty()))
- {
- if (! quietInstall.isPresent())
- {
- Message message = INFO_INSTALLDS_STATUS_IMPORTING_LDIF.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- }
-
- // Use the ImportLDIF tool to perform the import.
- argList = new ArrayList<String>();
- argList.add("-C");
- argList.add(configClassName);
- argList.add("-f");
- argList.add(configFileName);
- argList.add("-n");
- argList.add("userRoot");
-
- for (String s : ldifFiles)
- {
- if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
- {
- argList.add("-t");
- }
- else
- {
- argList.add("-l");
- }
- argList.add(s);
- }
-
- if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
- {
- argList.add("-s");
- argList.add("0");
- }
-
- if (populateType == POPULATE_TYPE_BASE_ONLY)
- {
- argList.add("-q");
- }
-
- String[] importLDIFArguments = new String[argList.size()];
- argList.toArray(importLDIFArguments);
-
- returnValue = ImportLDIF.mainImportLDIF(importLDIFArguments);
- if (returnValue != 0)
- {
- Message message = ERR_INSTALLDS_IMPORT_UNSUCCESSFUL.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- return returnValue;
- }
- else
- {
- Message message = INFO_INSTALLDS_IMPORT_SUCCESSFUL.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- }
- }
-
-
- // Try to write a file that can be used to set the JAVA_HOME environment
- // variable for the administrative scripts and client tools provided with
- // the server. If this fails, then it's not a big deal.
- try
- {
- String serverRoot = System.getenv("INSTANCE_ROOT");
- if ((serverRoot == null) || (serverRoot.length() == 0))
- {
- File f = new File(configFileName);
- serverRoot = f.getParentFile().getParentFile().getAbsolutePath();
- }
-
- // This isn't likely to happen, and it's not a serious problem even if it
- // does.
- SetupUtils.writeSetJavaHome(serverRoot);
- } catch (Exception e) {}
-
- if (enableService)
- {
- Message message = INFO_INSTALLDS_ENABLING_WINDOWS_SERVICE.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- int code = ConfigureWindowsService.enableService(System.out,
- System.err);
-
- switch (code)
- {
- case ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
- break;
- case ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
- break;
- default:
- // It did not work.
- return code;
- }
- }
-
- // If we've gotten here, then everything seems to have gone smoothly.
- if (! quietInstall.isPresent())
- {
- Message message = INFO_INSTALLDS_STATUS_SUCCESS.get();
- System.out.println(wrapText(message, MAX_LINE_WIDTH));
- }
-
- return 0;
+ uData.setEnableWindowsService(enableService);
}
-
-
/**
- * Interactively prompts (on standard output) the user to provide a Boolean
- * value. The answer provided must be one of "true", "t", "yes", "y",
- * "false", "f", "no", or "n", ignoring capitalization. It will keep
- * prompting until an acceptable value is given.
- *
- * @param prompt The prompt to present to the user.
- * @param defaultValue The default value to assume if the user presses ENTER
- * without typing anything, or <CODE>null</CODE> if
- * there should not be a default and the user must
- * explicitly provide a value.
- *
- * @return The <CODE>boolean</CODE> value read from the user input.
+ * This method updates the contents of a UserData object with what the user
+ * specified in the command-line for the Directory Manager parameters.
+ * If the user did not provide explicitly the data, it prompts the user to
+ * provide it.
+ * @param uData the UserData object to be updated.
*/
- private static boolean promptForBoolean(Message prompt, Boolean defaultValue)
+ private void promptIfRequiredForStartServer(UserData uData)
{
- String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
- while (true)
+ boolean startServer = false;
+ if (!argParser.doNotStartArg.isPresent())
{
- System.out.println();
- System.out.println(wrappedPrompt);
+ printLineBreak();
+ Message message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
+ startServer = confirm(message);
+ }
+ uData.setStartServer(startServer);
+ }
- if (defaultValue == null)
+ /**
+ * Checks that the provided parameters are valid to access an existing
+ * keystore. This method adds the encountered errors to the provided
+ * list of Message. It also adds the alias (nicknames) found to the provided
+ * list of String.
+ * @param type the type of keystore.
+ * @param path the path of the keystore.
+ * @param pwd the password (PIN) to access the keystore.
+ * @param certNickname the certificate nickname that we are looking for (or
+ * null if we just one to get the one that is in the keystore).
+ * @param errorMessages the list that will be updated with the errors
+ * encountered.
+ * @param nicknameList the list that will be updated with the nicknames found
+ * in the keystore.
+ */
+ private void checkCertificateInKeystore(SecurityOptions.CertificateType type,
+ String path, String pwd, String certNickname,
+ LinkedList<Message> errorMessages, LinkedList<String> nicknameList)
+ {
+ boolean errorWithPath = false;
+ if (type != SecurityOptions.CertificateType.PKCS11)
+ {
+ File f = new File(path);
+ if (!f.exists())
{
- System.out.print(": ");
+ errorMessages.add(INFO_KEYSTORE_PATH_DOES_NOT_EXIST.get());
+ errorWithPath = true;
}
- else
+ else if (!f.isFile())
{
- System.out.print("[");
-
- if (defaultValue)
+ errorMessages.add(INFO_KEYSTORE_PATH_NOT_A_FILE.get());
+ errorWithPath = true;
+ }
+ }
+ if (!errorWithPath)
+ {
+ try
+ {
+ CertificateManager certManager;
+ switch (type)
{
- System.out.print(INFO_INSTALLDS_PROMPT_VALUE_YES.get());
+ case JKS:
+ certManager = new CertificateManager(
+ path,
+ CertificateManager.KEY_STORE_TYPE_JKS,
+ pwd);
+ break;
+
+ case PKCS12:
+ certManager = new CertificateManager(
+ path,
+ CertificateManager.KEY_STORE_TYPE_PKCS12,
+ pwd);
+ break;
+
+ case PKCS11:
+ certManager = new CertificateManager(
+ CertificateManager.KEY_STORE_PATH_PKCS11,
+ CertificateManager.KEY_STORE_TYPE_PKCS11,
+ pwd);
+ break;
+
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
+ }
+ String[] aliases = certManager.getCertificateAliases();
+ if ((aliases == null) || (aliases.length == 0))
+ {
+ // Could not retrieve any certificate
+ switch (type)
+ {
+ case JKS:
+ errorMessages.add(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST.get());
+ break;
+
+ case PKCS12:
+ errorMessages.add(INFO_JKS_KEYSTORE_DOES_NOT_EXIST.get());
+ break;
+ case PKCS11:
+ errorMessages.add(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST.get());
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
+ }
}
else
{
- System.out.print(INFO_INSTALLDS_PROMPT_VALUE_NO.get());
+ for (int i=0; i<aliases.length; i++)
+ {
+ nicknameList.add(aliases[i]);
+ }
+ String aliasString = Utils.getStringFromCollection(nicknameList,
+ ", ");
+ if (certNickname != null)
+ {
+ // Check if the cert alias is in the list.
+ boolean found = false;
+ for (int i=0; i<aliases.length && !found; i++)
+ {
+ found = aliases[i].equalsIgnoreCase(certNickname);
+ }
+ if (!found)
+ {
+ errorMessages.add(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND.get(
+ aliasString));
+ }
+ }
+ else if (aliases.length > 1)
+ {
+ errorMessages.add(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME.get(
+ aliasString));
+ }
}
-
- System.out.print("]: ");
}
-
- System.out.flush();
-
- String response = toLowerCase(readLine());
- if (response.equals("true") || response.equals("yes") ||
- response.equals("t") || response.equals("y"))
+ catch (KeyStoreException ke)
{
- return true;
- }
- else if (response.equals("false") || response.equals("no") ||
- response.equals("f") || response.equals("n"))
- {
- return false;
- }
- else if (response.equals(""))
- {
- if (defaultValue == null)
+ // Could not access to the keystore: because the password is no good,
+ // because the provided file is not a valid keystore, etc.
+ switch (type)
{
- Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
+ case JKS:
+ errorMessages.add(INFO_ERROR_ACCESSING_JKS_KEYSTORE.get());
+ break;
+
+ case PKCS12:
+ errorMessages.add(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE.get());
+ break;
+ case PKCS11:
+ errorMessages.add(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE.get());
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
}
- else
- {
- return defaultValue;
- }
- }
- else
- {
- Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
}
}
}
+ /**
+ * Creates a SecurityOptions object that corresponds to the provided
+ * parameters. If the parameters are not valid, it prompts the user to
+ * provide them.
+ * @param type the keystore type.
+ * @param enableSSL whether to enable SSL or not.
+ * @param enableStartTLS whether to enable StartTLS or not.
+ * @param ldapsPort the LDAPS port to use.
+ * @return a SecurityOptions object that corresponds to the provided
+ * parameters (or to what the user provided after being prompted).
+ */
+ private SecurityOptions createSecurityOptionsPrompting(
+ SecurityOptions.CertificateType type, boolean enableSSL,
+ boolean enableStartTLS, int ldapsPort)
+ {
+ SecurityOptions securityOptions;
+ String path;
+ String certNickname = argParser.certNicknameArg.getValue();
+ String pwd = argParser.getKeyStorePassword();
+ Message pathPrompt;
+ String defaultPathValue;
+ switch (type)
+ {
+ case JKS:
+ path = argParser.useJavaKeyStoreArg.getValue();
+ pathPrompt = INFO_INSTALLDS_PROMPT_JKS_PATH.get();
+ defaultPathValue = argParser.useJavaKeyStoreArg.getValue();
+ break;
+ case PKCS11:
+ path = null;
+ defaultPathValue = null;
+ pathPrompt = null;
+ break;
+ case PKCS12:
+ path = argParser.usePkcs12Arg.getValue();
+ defaultPathValue = argParser.usePkcs12Arg.getValue();
+ pathPrompt = INFO_INSTALLDS_PROMPT_PKCS12_PATH.get();
+ break;
+ default:
+ throw new IllegalStateException(
+ "Called promptIfRequiredCertificate with invalid type: "+type);
+ }
+ LinkedList<Message> errorMessages = new LinkedList<Message>();
+ LinkedList<String> keystoreAliases = new LinkedList<String>();
+ boolean firstTry = true;
+
+ while ((errorMessages.size() > 0) || firstTry)
+ {
+ boolean prompted = false;
+ if (errorMessages.size() > 0)
+ {
+ printLineBreak();
+ printErrorMessage(Utils.getMessageFromCollection(errorMessages,
+ formatter.getLineBreak().toString()));
+ }
+
+ if (type != SecurityOptions.CertificateType.PKCS11)
+ {
+ if (containsKeyStorePathErrorMessage(errorMessages) || (path == null))
+ {
+ printLineBreak();
+ path = promptForString(pathPrompt, defaultPathValue);
+ prompted = true;
+ if (pwd != null)
+ {
+ errorMessages.clear();
+ keystoreAliases.clear();
+ checkCertificateInKeystore(type, path, pwd, certNickname,
+ errorMessages, keystoreAliases);
+ if (!errorMessages.isEmpty())
+ {
+ // Reset password: this might be a new keystore
+ pwd = null;
+ }
+ }
+ }
+ }
+ if (containsKeyStorePasswordErrorMessage(errorMessages) ||
+ (pwd == null))
+ {
+ if (!prompted)
+ {
+ printLineBreak();
+ }
+ pwd = promptForPassword(
+ INFO_INSTALLDS_PROMPT_KEYSTORE_PASSWORD.get());
+ }
+ if (containsCertNicknameErrorMessage(errorMessages))
+ {
+ if (!prompted)
+ {
+ printLineBreak();
+ }
+ certNickname = promptForCertificateNickname(keystoreAliases);
+ }
+ errorMessages.clear();
+ keystoreAliases.clear();
+ checkCertificateInKeystore(type, path, pwd, certNickname, errorMessages,
+ keystoreAliases);
+ firstTry = false;
+ }
+ if (certNickname == null)
+ {
+ certNickname = keystoreAliases.getFirst();
+ }
+ switch (type)
+ {
+ case JKS:
+ securityOptions = SecurityOptions.createJKSCertificateOptions(
+ path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ break;
+ case PKCS12:
+ securityOptions = SecurityOptions.createPKCS12CertificateOptions(
+ path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ break;
+ case PKCS11:
+ securityOptions = SecurityOptions.createPKCS11CertificateOptions(
+ pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+ break;
+ default:
+ throw new IllegalStateException(
+ "Called createSecurityOptionsPrompting with invalid type: "+type);
+ }
+ return securityOptions;
+ }
+
+ /**
+ * Tells if any of the error messages provided corresponds to a problem
+ * with the key store path.
+ * @param msgs the messages to analyze.
+ * @return <CODE>true</CODE> if any of the error messages provided corresponds
+ * to a problem with the key store path and <CODE>false</CODE> otherwise.
+ */
+ private boolean containsKeyStorePathErrorMessage(Collection<Message> msgs)
+ {
+ boolean found = false;
+ for (Message msg : msgs)
+ {
+ if (msg.getDescriptor().equals(INFO_KEYSTORE_PATH_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_KEYSTORE_PATH_NOT_A_FILE) ||
+ msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
+ {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Tells if any of the error messages provided corresponds to a problem
+ * with the key store password.
+ * @param msgs the messages to analyze.
+ * @return <CODE>true</CODE> if any of the error messages provided corresponds
+ * to a problem with the key store password and <CODE>false</CODE> otherwise.
+ */
+ private boolean containsKeyStorePasswordErrorMessage(Collection<Message> msgs)
+ {
+ boolean found = false;
+ for (Message msg : msgs)
+ {
+ if (msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
+ msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
+ {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Tells if any of the error messages provided corresponds to a problem
+ * with the certificate nickname.
+ * @param msgs the messages to analyze.
+ * @return <CODE>true</CODE> if any of the error messages provided corresponds
+ * to a problem with the certificate nickname and <CODE>false</CODE>
+ * otherwise.
+ */
+ private boolean containsCertNicknameErrorMessage(Collection<Message> msgs)
+ {
+ boolean found = false;
+ for (Message msg : msgs)
+ {
+ if (msg.getDescriptor().equals(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND) ||
+ msg.getDescriptor().equals(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME))
+ {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
/**
* Interactively prompts (on standard output) the user to provide an integer
@@ -1190,308 +1664,81 @@
*
* @return The <CODE>int</CODE> value read from the user input.
*/
- private static int promptForInteger(Message prompt, Integer defaultValue,
+ private int promptForInteger(Message prompt, Integer defaultValue,
Integer lowerBound, Integer upperBound)
{
- String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
- while (true)
+ int returnValue = -1;
+ while (returnValue == -1)
{
- System.out.println();
- System.out.println(wrappedPrompt);
-
- if (defaultValue == null)
- {
- System.out.print(": ");
- }
- else
- {
- System.out.print("[");
- System.out.print(defaultValue);
- System.out.print("]: ");
- }
-
- System.out.flush();
-
- String response = readLine();
- if (response.equals(""))
+ String s = promptForString(prompt, String.valueOf(defaultValue));
+ if (s.equals(""))
{
if (defaultValue == null)
{
Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
+ printErrorMessage(message);
+ printLineBreak();
}
else
{
- return defaultValue;
+ returnValue = defaultValue;
}
}
else
{
try
{
- int intValue = Integer.parseInt(response);
+ int intValue = Integer.parseInt(s);
if ((lowerBound != null) && (intValue < lowerBound))
{
Message message =
ERR_INSTALLDS_INTEGER_BELOW_LOWER_BOUND.get(lowerBound);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
+ printErrorMessage(message);
+ printLineBreak();
}
else if ((upperBound != null) && (intValue > upperBound))
{
Message message =
ERR_INSTALLDS_INTEGER_ABOVE_UPPER_BOUND.get(upperBound);
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
+ printErrorMessage(message);
+ printLineBreak();
}
else
{
- return intValue;
+ returnValue = intValue;
}
}
catch (NumberFormatException nfe)
{
Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
+ printErrorMessage(message);
+ printLineBreak();
}
}
}
+ return returnValue;
}
-
-
/**
- * Interactively prompts (on standard output) the user to provide a DN value.
- * Any non-empty string will be allowed if it can be parsed as a valid DN (the
- * empty string will indicate that the default should be used, if there is
- * one).
- *
- * @param prompt The prompt to present to the user.
- * @param defaultValue The default value to assume if the user presses ENTER
- * without typing anything, or <CODE>null</CODE> if
- * there should not be a default and the user must
- * explicitly provide a value.
- *
- * @return The DN value read from the user.
+ * Prompts the user to accept on the certificates that appears on the list
+ * and returns the chosen certificate nickname.
+ * @param nicknames the list of certificates the user must choose from.
+ * @return the chosen certificate nickname.
*/
- private static DN promptForDN(Message prompt, String defaultValue)
+ private String promptForCertificateNickname(LinkedList<String> nicknames)
{
- String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
- while (true)
+ String nickname = null;
+ while (nickname == null)
{
- System.out.println();
- System.out.println(wrappedPrompt);
-
- if (defaultValue == null)
+ for (String n : nicknames)
{
- System.out.print(": ");
- }
- else
- {
- System.out.print("[");
- System.out.print(defaultValue);
- System.out.print("]: ");
- }
-
- System.out.flush();
-
- String response = readLine();
- if (response.equals(""))
- {
- if (defaultValue == null)
+ if (confirm(INFO_INSTALLDS_PROMPT_CERTNICKNAME.get(n)))
{
- Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- try
- {
- return DN.decode(defaultValue);
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- }
- }
- else
- {
- try
- {
- return DN.decode(response);
- }
- catch (Exception e)
- {
- Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- }
- }
- }
-
-
-
- /**
- * Interactively prompts (on standard output) the user to provide a string
- * value. Any non-empty string will be allowed (the empty string will
- * indicate that the default should be used, if there is one).
- *
- * @param prompt The prompt to present to the user.
- * @param defaultValue The default value to assume if the user presses ENTER
- * without typing anything, or <CODE>null</CODE> if
- * there should not be a default and the user must
- * explicitly provide a value.
- *
- * @return The string value read from the user.
- */
- private static String promptForString(Message prompt, String defaultValue)
- {
- System.out.println();
- String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
- while (true)
- {
- System.out.println(wrappedPrompt);
-
- if (defaultValue == null)
- {
- System.out.print(": ");
- }
- else
- {
- System.out.print("[");
- System.out.print(defaultValue);
- System.out.print("]: ");
- }
-
- System.out.flush();
-
- String response = readLine();
- if (response.equals(""))
- {
- if (defaultValue == null)
- {
- Message message = ERR_INSTALLDS_INVALID_STRING_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- return defaultValue;
- }
- }
- else
- {
- return response;
- }
- }
- }
-
-
-
- /**
- * Interactively prompts (on standard output) the user to provide a string
- * value. The response that the user provides will not be echoed, and it must
- * be entered twice for confirmation. No default value will be allowed, and
- * the string entered must contain at least one character.
- *
- * @param initialPrompt The initial prompt to present to the user.
- * @param reEntryPrompt The prompt to present to the user when requesting
- * that the value be re-entered for confirmation.
- *
- * @return The string value read from the user.
- */
- private static char[] promptForPassword(Message initialPrompt,
- Message reEntryPrompt)
- {
- String wrappedInitialPrompt = wrapText(initialPrompt, MAX_LINE_WIDTH);
- String wrappedReEntryPrompt = wrapText(reEntryPrompt, MAX_LINE_WIDTH);
-
- while (true)
- {
- System.out.println();
- System.out.print(wrappedInitialPrompt);
- System.out.print(": ");
- System.out.flush();
-
- char[] password = PasswordReader.readPassword();
- if ((password == null) || (password.length == 0))
- {
- Message message = ERR_INSTALLDS_INVALID_PASSWORD_RESPONSE.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- System.out.print(wrappedReEntryPrompt);
- System.out.print(": ");
- System.out.flush();
- char[] confirmedPassword = PasswordReader.readPassword();
- if ((confirmedPassword == null) ||
- (! Arrays.equals(password, confirmedPassword)))
- {
- Message message = ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get();
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
- }
- else
- {
- return password;
- }
- }
- }
- }
-
-
-
- /**
- * Reads a line of text from standard input.
- *
- * @return The line of text read from standard input, or <CODE>null</CODE>
- * if the end of the stream is reached or an error occurs while
- * attempting to read the response.
- */
- private static String readLine()
- {
- try
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- while (true)
- {
- int b = System.in.read();
- if ((b < 0) || (b == '\n'))
- {
+ nickname = n;
break;
}
- else if (b == '\r')
- {
- int b2 = System.in.read();
- if (b2 == '\n')
- {
- break;
- }
- else
- {
- baos.write(b);
- baos.write(b2);
- }
- }
- else
- {
- baos.write(b);
- }
}
-
- return new String(baos.toByteArray(), "UTF-8");
}
- catch (Exception e)
- {
- Message message =
- ERR_INSTALLDS_ERROR_READING_FROM_STDIN.get(String.valueOf(e));
- System.err.println(wrapText(message, MAX_LINE_WIDTH));
-
- return null;
- }
+ return nickname;
}
}
-
--
Gitblit v1.10.0