Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2012-2021 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright 2012-2021 Ping Identity Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (C) 2012-2021 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.util;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import com.unboundid.ldap.sdk.BindRequest;
import com.unboundid.ldap.sdk.ExtendedResult;
import com.unboundid.ldap.sdk.InternalSDKHelper;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPConnectionOptions;
import com.unboundid.ldap.sdk.LDAPConnectionPool;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.PostConnectProcessor;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.ServerSet;
import com.unboundid.ldap.sdk.SimpleBindRequest;
import com.unboundid.ldap.sdk.SingleServerSet;
import com.unboundid.ldap.sdk.StartTLSPostConnectProcessor;
import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.BooleanArgument;
import com.unboundid.util.args.DNArgument;
import com.unboundid.util.args.FileArgument;
import com.unboundid.util.args.IntegerArgument;
import com.unboundid.util.args.StringArgument;
import com.unboundid.util.ssl.AggregateTrustManager;
import com.unboundid.util.ssl.KeyStoreKeyManager;
import com.unboundid.util.ssl.SSLUtil;
import com.unboundid.util.ssl.TrustAllTrustManager;
import com.unboundid.util.ssl.TrustStoreTrustManager;
import static com.unboundid.util.UtilityMessages.*;
/**
* This class provides a basis for developing command-line tools that have the
* ability to communicate with multiple directory servers, potentially with
* very different settings for each. For example, it may be used to help create
* tools that move or compare data from one server to another.
*
* Each server will be identified by a prefix and/or suffix that will be added
* to the argument name (e.g., if the first server has a prefix of "source",
* then the "hostname" argument will actually be "sourceHostname"). The
* base names for the arguments this class supports include:
*
*
hostname -- Specifies the address of the directory server. If this
* isn't specified, then a default of "localhost" will be used.
*
port -- specifies the port number of the directory server. If this
* isn't specified, then a default port of 389 will be used.
*
bindDN -- Specifies the DN to use to bind to the directory server using
* simple authentication. If this isn't specified, then simple
* authentication will not be performed.
*
bindPassword -- Specifies the password to use when binding with simple
* authentication or a password-based SASL mechanism.
*
bindPasswordFile -- Specifies the path to a file containing the
* password to use when binding with simple authentication or a
* password-based SASL mechanism.
*
useSSL -- Indicates that communication with the server should be
* secured using SSL.
*
useStartTLS -- Indicates that communication with the server should be
* secured using StartTLS.
*
"--defaultTrust" -- Indicates that the client should use a default,
* non-interactive mechanism for determining whether to trust any
* presented server certificate.
*
trustAll -- Indicates that the client should trust any certificate
* that the server presents to it.
*
keyStorePath -- Specifies the path to the key store to use to obtain
* client certificates.
*
keyStorePassword -- Specifies the password to use to access the
* contents of the key store.
*
keyStorePasswordFile -- Specifies the path ot a file containing the
* password to use to access the contents of the key store.
*
keyStoreFormat -- Specifies the format to use for the key store
* file.
*
trustStorePath -- Specifies the path to the trust store to use to
* obtain client certificates.
*
trustStorePassword -- Specifies the password to use to access the
* contents of the trust store.
*
trustStorePasswordFile -- Specifies the path ot a file containing the
* password to use to access the contents of the trust store.
*
trustStoreFormat -- Specifies the format to use for the trust store
* file.
*
certNickname -- Specifies the nickname of the client certificate to
* use when performing SSL client authentication.
*
saslOption -- Specifies a SASL option to use when performing SASL
* authentication.
*
* If SASL authentication is to be used, then a "mech" SASL option must be
* provided to specify the name of the SASL mechanism to use. Depending on the
* SASL mechanism, additional SASL options may be required or optional.
*/
@Extensible()
@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_NOT_THREADSAFE)
public abstract class MultiServerLDAPCommandLineTool
extends CommandLineTool
{
// The set of prefixes and suffixes that will be used for server names.
private final int numServers;
@Nullable private final String[] serverNamePrefixes;
@Nullable private final String[] serverNameSuffixes;
// The set of arguments used to hold information about connection properties.
@NotNull private final BooleanArgument[] defaultTrust;
@NotNull private final BooleanArgument[] trustAll;
@NotNull private final BooleanArgument[] useSSL;
@NotNull private final BooleanArgument[] useStartTLS;
@NotNull private final DNArgument[] bindDN;
@NotNull private final FileArgument[] bindPasswordFile;
@NotNull private final FileArgument[] keyStorePasswordFile;
@NotNull private final FileArgument[] trustStorePasswordFile;
@NotNull private final IntegerArgument[] port;
@NotNull private final StringArgument[] bindPassword;
@NotNull private final StringArgument[] certificateNickname;
@NotNull private final StringArgument[] host;
@NotNull private final StringArgument[] keyStoreFormat;
@NotNull private final StringArgument[] keyStorePath;
@NotNull private final StringArgument[] keyStorePassword;
@NotNull private final StringArgument[] saslOption;
@NotNull private final StringArgument[] trustStoreFormat;
@NotNull private final StringArgument[] trustStorePath;
@NotNull private final StringArgument[] trustStorePassword;
// Variables used when creating and authenticating connections.
@NotNull private final BindRequest[] bindRequest;
@NotNull private final ServerSet[] serverSet;
@NotNull private final SSLSocketFactory[] startTLSSocketFactory;
// An atomic reference to an aggregate trust manager that will check a
// JVM-default set of trusted issuers, and then its own cache, before
// prompting the user about whether to trust the presented certificate chain.
// Re-using this trust manager will allow the tool to benefit from a common
// cache if multiple connections are needed.
@NotNull private final AtomicReference
promptTrustManager;
/**
* Creates a new instance of this multi-server LDAP command-line tool. At
* least one of the set of server name prefixes and suffixes must be
* non-{@code null}. If both are non-{@code null}, then they must have the
* same number of elements.
*
* @param outStream The output stream to use for standard output.
* It may be {@code System.out} for the JVM's
* default standard output stream, {@code null} if
* no output should be generated, or a custom
* output stream if the output should be sent to
* an alternate location.
* @param errStream The output stream to use for standard error.
* It may be {@code System.err} for the JVM's
* default standard error stream, {@code null} if
* no output should be generated, or a custom
* output stream if the output should be sent to
* an alternate location.
* @param serverNamePrefixes The prefixes to include before the names of
* each of the parameters to identify each server.
* It may be {@code null} if only suffixes should
* be used.
* @param serverNameSuffixes The suffixes to include after the names of each
* of the parameters to identify each server. It
* may be {@code null} if only prefixes should be
* used.
*
* @throws LDAPSDKUsageException If both the sets of server name prefixes
* and suffixes are {@code null} or empty, or
* if both sets are non-{@code null} but have
* different numbers of elements.
*/
public MultiServerLDAPCommandLineTool(@Nullable final OutputStream outStream,
@Nullable final OutputStream errStream,
@Nullable final String[] serverNamePrefixes,
@Nullable final String[] serverNameSuffixes)
throws LDAPSDKUsageException
{
super(outStream, errStream);
promptTrustManager = new AtomicReference<>();
this.serverNamePrefixes = serverNamePrefixes;
this.serverNameSuffixes = serverNameSuffixes;
if (serverNamePrefixes == null)
{
if (serverNameSuffixes == null)
{
throw new LDAPSDKUsageException(
ERR_MULTI_LDAP_TOOL_PREFIXES_AND_SUFFIXES_NULL.get());
}
else
{
numServers = serverNameSuffixes.length;
}
}
else
{
numServers = serverNamePrefixes.length;
if ((serverNameSuffixes != null) &&
(serverNamePrefixes.length != serverNameSuffixes.length))
{
throw new LDAPSDKUsageException(
ERR_MULTI_LDAP_TOOL_PREFIXES_AND_SUFFIXES_MISMATCH.get());
}
}
if (numServers == 0)
{
throw new LDAPSDKUsageException(
ERR_MULTI_LDAP_TOOL_PREFIXES_AND_SUFFIXES_EMPTY.get());
}
defaultTrust = new BooleanArgument[numServers];
trustAll = new BooleanArgument[numServers];
useSSL = new BooleanArgument[numServers];
useStartTLS = new BooleanArgument[numServers];
bindDN = new DNArgument[numServers];
bindPasswordFile = new FileArgument[numServers];
keyStorePasswordFile = new FileArgument[numServers];
trustStorePasswordFile = new FileArgument[numServers];
port = new IntegerArgument[numServers];
bindPassword = new StringArgument[numServers];
certificateNickname = new StringArgument[numServers];
host = new StringArgument[numServers];
keyStoreFormat = new StringArgument[numServers];
keyStorePath = new StringArgument[numServers];
keyStorePassword = new StringArgument[numServers];
saslOption = new StringArgument[numServers];
trustStoreFormat = new StringArgument[numServers];
trustStorePath = new StringArgument[numServers];
trustStorePassword = new StringArgument[numServers];
bindRequest = new BindRequest[numServers];
serverSet = new ServerSet[numServers];
startTLSSocketFactory = new SSLSocketFactory[numServers];
}
/**
* {@inheritDoc}
*/
@Override()
public final void addToolArguments(@NotNull final ArgumentParser parser)
throws ArgumentException
{
for (int i=0; i < numServers; i++)
{
final StringBuilder groupNameBuffer = new StringBuilder();
if (serverNamePrefixes != null)
{
final String prefix = serverNamePrefixes[i].replace('-', ' ').trim();
groupNameBuffer.append(StaticUtils.capitalize(prefix, true));
}
if (serverNameSuffixes != null)
{
if (groupNameBuffer.length() > 0)
{
groupNameBuffer.append(' ');
}
final String suffix = serverNameSuffixes[i].replace('-', ' ').trim();
groupNameBuffer.append(StaticUtils.capitalize(suffix, true));
}
groupNameBuffer.append(' ');
groupNameBuffer.append(INFO_MULTI_LDAP_TOOL_GROUP_CONN_AND_AUTH.get());
final String groupName = groupNameBuffer.toString();
host[i] = new StringArgument(null, genArgName(i, "hostname"), true, 1,
INFO_LDAP_TOOL_PLACEHOLDER_HOST.get(),
INFO_LDAP_TOOL_DESCRIPTION_HOST.get(), "localhost");
if (includeAlternateLongIdentifiers())
{
host[i].addLongIdentifier(genDashedArgName(i, "hostname"), true);
host[i].addLongIdentifier(genArgName(i, "host"), true);
host[i].addLongIdentifier(genDashedArgName(i, "host"), true);
host[i].addLongIdentifier(genArgName(i, "address"), true);
host[i].addLongIdentifier(genDashedArgName(i, "address"), true);
}
host[i].setArgumentGroupName(groupName);
parser.addArgument(host[i]);
port[i] = new IntegerArgument(null, genArgName(i, "port"), true, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PORT.get(),
INFO_LDAP_TOOL_DESCRIPTION_PORT.get(), 1, 65_535, 389);
port[i].setArgumentGroupName(groupName);
if (includeAlternateLongIdentifiers())
{
port[i].addLongIdentifier(genDashedArgName(i, "port"), true);
}
parser.addArgument(port[i]);
bindDN[i] = new DNArgument(null, genArgName(i, "bindDN"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_DN.get(),
INFO_LDAP_TOOL_DESCRIPTION_BIND_DN.get());
if (includeAlternateLongIdentifiers())
{
bindDN[i].addLongIdentifier(genDashedArgName(i, "bind-dn"), true);
}
bindDN[i].setArgumentGroupName(groupName);
parser.addArgument(bindDN[i]);
bindPassword[i] = new StringArgument(null, genArgName(i, "bindPassword"),
false, 1, INFO_LDAP_TOOL_PLACEHOLDER_PASSWORD.get(),
INFO_LDAP_TOOL_DESCRIPTION_BIND_PW.get());
if (includeAlternateLongIdentifiers())
{
bindPassword[i].addLongIdentifier(genDashedArgName(i, "bind-password"),
true);
}
bindPassword[i].setSensitive(true);
bindPassword[i].setArgumentGroupName(groupName);
parser.addArgument(bindPassword[i]);
bindPasswordFile[i] = new FileArgument(null,
genArgName(i, "bindPasswordFile"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PATH.get(),
INFO_LDAP_TOOL_DESCRIPTION_BIND_PW_FILE.get(), true, true, true,
false);
if (includeAlternateLongIdentifiers())
{
bindPasswordFile[i].addLongIdentifier(genDashedArgName(i,
"bind-password-file"), true);
}
bindPasswordFile[i].setArgumentGroupName(groupName);
parser.addArgument(bindPasswordFile[i]);
useSSL[i] = new BooleanArgument(null, genArgName(i, "useSSL"), 1,
INFO_LDAP_TOOL_DESCRIPTION_USE_SSL.get());
if (includeAlternateLongIdentifiers())
{
useSSL[i].addLongIdentifier(genDashedArgName(i, "use-ssl"), true);
}
useSSL[i].setArgumentGroupName(groupName);
parser.addArgument(useSSL[i]);
useStartTLS[i] = new BooleanArgument(null, genArgName(i, "useStartTLS"),
1, INFO_LDAP_TOOL_DESCRIPTION_USE_START_TLS.get());
if (includeAlternateLongIdentifiers())
{
useStartTLS[i].addLongIdentifier(genDashedArgName(i, "use-start-tls"),
true);
}
useStartTLS[i].setArgumentGroupName(groupName);
parser.addArgument(useStartTLS[i]);
final String defaultTrustArgDesc;
if (InternalSDKHelper.getPingIdentityServerRoot() != null)
{
defaultTrustArgDesc =
INFO_LDAP_TOOL_DESCRIPTION_DEFAULT_TRUST_WITH_PING_DS.get();
}
else
{
defaultTrustArgDesc =
INFO_LDAP_TOOL_DESCRIPTION_DEFAULT_TRUST_WITHOUT_PING_DS.get();
}
defaultTrust[i] = new BooleanArgument(null,
genArgName(i, "defaultTrust"), 1, defaultTrustArgDesc);
defaultTrust[i].setArgumentGroupName(groupName);
if (includeAlternateLongIdentifiers())
{
defaultTrust[i].addLongIdentifier(
genDashedArgName(i, "default-trust"), true);
defaultTrust[i].addLongIdentifier(
genArgName(i, "useDefaultTrust"), true);
defaultTrust[i].addLongIdentifier(
genDashedArgName(i, "use-default-trust"), true);
}
parser.addArgument(defaultTrust[i]);
trustAll[i] = new BooleanArgument(null, genArgName(i, "trustAll"), 1,
INFO_LDAP_TOOL_DESCRIPTION_TRUST_ALL.get());
if (includeAlternateLongIdentifiers())
{
trustAll[i].addLongIdentifier(genDashedArgName(i, "trust-all"), true);
}
trustAll[i].setArgumentGroupName(groupName);
parser.addArgument(trustAll[i]);
keyStorePath[i] = new StringArgument(null, genArgName(i, "keyStorePath"),
false, 1, INFO_LDAP_TOOL_PLACEHOLDER_PATH.get(),
INFO_LDAP_TOOL_DESCRIPTION_KEY_STORE_PATH.get());
if (includeAlternateLongIdentifiers())
{
keyStorePath[i].addLongIdentifier(genDashedArgName(i, "key-store-path"),
true);
}
keyStorePath[i].setArgumentGroupName(groupName);
parser.addArgument(keyStorePath[i]);
keyStorePassword[i] = new StringArgument(null,
genArgName(i, "keyStorePassword"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PASSWORD.get(),
INFO_LDAP_TOOL_DESCRIPTION_KEY_STORE_PASSWORD.get());
if (includeAlternateLongIdentifiers())
{
keyStorePassword[i].addLongIdentifier(genDashedArgName(i,
"key-store-password"), true);
}
keyStorePassword[i].setSensitive(true);
keyStorePassword[i].setArgumentGroupName(groupName);
parser.addArgument(keyStorePassword[i]);
keyStorePasswordFile[i] = new FileArgument(null,
genArgName(i, "keyStorePasswordFile"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PATH.get(),
INFO_LDAP_TOOL_DESCRIPTION_KEY_STORE_PASSWORD_FILE.get(), true,
true, true, false);
if (includeAlternateLongIdentifiers())
{
keyStorePasswordFile[i].addLongIdentifier(genDashedArgName(i,
"key-store-password-file"), true);
}
keyStorePasswordFile[i].setArgumentGroupName(groupName);
parser.addArgument(keyStorePasswordFile[i]);
keyStoreFormat[i] = new StringArgument(null,
genArgName(i, "keyStoreFormat"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_FORMAT.get(),
INFO_LDAP_TOOL_DESCRIPTION_KEY_STORE_FORMAT.get());
if (includeAlternateLongIdentifiers())
{
keyStoreFormat[i].addLongIdentifier(genDashedArgName(i,
"key-store-format"), true);
keyStoreFormat[i].addLongIdentifier(genArgName(i, "keyStoreType"),
true);
keyStoreFormat[i].addLongIdentifier(genDashedArgName(i,
"key-store-type"), true);
}
keyStoreFormat[i].setArgumentGroupName(groupName);
parser.addArgument(keyStoreFormat[i]);
trustStorePath[i] = new StringArgument(null,
genArgName(i, "trustStorePath"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PATH.get(),
INFO_LDAP_TOOL_DESCRIPTION_TRUST_STORE_PATH.get());
if (includeAlternateLongIdentifiers())
{
trustStorePath[i].addLongIdentifier(genDashedArgName(i,
"trust-store-path"), true);
}
trustStorePath[i].setArgumentGroupName(groupName);
parser.addArgument(trustStorePath[i]);
trustStorePassword[i] = new StringArgument(null,
genArgName(i, "trustStorePassword"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PASSWORD.get(),
INFO_LDAP_TOOL_DESCRIPTION_TRUST_STORE_PASSWORD.get());
if (includeAlternateLongIdentifiers())
{
trustStorePassword[i].addLongIdentifier(genDashedArgName(i,
"trust-store-password"), true);
}
trustStorePassword[i].setSensitive(true);
trustStorePassword[i].setArgumentGroupName(groupName);
parser.addArgument(trustStorePassword[i]);
trustStorePasswordFile[i] = new FileArgument(null,
genArgName(i, "trustStorePasswordFile"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_PATH.get(),
INFO_LDAP_TOOL_DESCRIPTION_TRUST_STORE_PASSWORD_FILE.get(), true,
true, true, false);
if (includeAlternateLongIdentifiers())
{
trustStorePasswordFile[i].addLongIdentifier(genDashedArgName(i,
"trust-store-password-file"), true);
}
trustStorePasswordFile[i].setArgumentGroupName(groupName);
parser.addArgument(trustStorePasswordFile[i]);
trustStoreFormat[i] = new StringArgument(null,
genArgName(i, "trustStoreFormat"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_FORMAT.get(),
INFO_LDAP_TOOL_DESCRIPTION_TRUST_STORE_FORMAT.get());
if (includeAlternateLongIdentifiers())
{
trustStoreFormat[i].addLongIdentifier(genDashedArgName(i,
"trust-store-format"), true);
trustStoreFormat[i].addLongIdentifier(genArgName(i, "trustStoreType"),
true);
trustStoreFormat[i].addLongIdentifier(genDashedArgName(i,
"trust-store-type"), true);
}
trustStoreFormat[i].setArgumentGroupName(groupName);
parser.addArgument(trustStoreFormat[i]);
certificateNickname[i] = new StringArgument(null,
genArgName(i, "certNickname"), false, 1,
INFO_LDAP_TOOL_PLACEHOLDER_CERT_NICKNAME.get(),
INFO_LDAP_TOOL_DESCRIPTION_CERT_NICKNAME.get());
if (includeAlternateLongIdentifiers())
{
certificateNickname[i].addLongIdentifier(genDashedArgName(i,
"cert-nickname"), true);
certificateNickname[i].addLongIdentifier(genArgName(i,
"certificateNickname"), true);
certificateNickname[i].addLongIdentifier(genDashedArgName(i,
"certificate-nickname"), true);
}
certificateNickname[i].setArgumentGroupName(groupName);
parser.addArgument(certificateNickname[i]);
saslOption[i] = new StringArgument(null, genArgName(i, "saslOption"),
false, 0, INFO_LDAP_TOOL_PLACEHOLDER_SASL_OPTION.get(),
INFO_LDAP_TOOL_DESCRIPTION_SASL_OPTION.get());
if (includeAlternateLongIdentifiers())
{
saslOption[i].addLongIdentifier(genDashedArgName(i, "sasl-option"),
true);
}
saslOption[i].setArgumentGroupName(groupName);
parser.addArgument(saslOption[i]);
parser.addDependentArgumentSet(bindDN[i], bindPassword[i],
bindPasswordFile[i]);
parser.addExclusiveArgumentSet(useSSL[i], useStartTLS[i]);
parser.addExclusiveArgumentSet(bindPassword[i], bindPasswordFile[i]);
parser.addExclusiveArgumentSet(keyStorePassword[i],
keyStorePasswordFile[i]);
parser.addExclusiveArgumentSet(trustStorePassword[i],
trustStorePasswordFile[i]);
parser.addExclusiveArgumentSet(trustAll[i], trustStorePath[i]);
parser.addExclusiveArgumentSet(trustAll[i], defaultTrust[i]);
}
addNonLDAPArguments(parser);
}
/**
* Constructs the name to use for an argument from the given base and the
* appropriate prefix and suffix.
*
* @param index The index into the set of prefixes and suffixes.
* @param base The base name for the argument.
*
* @return The constructed argument name.
*/
@NotNull()
private String genArgName(final int index, @NotNull final String base)
{
final StringBuilder buffer = new StringBuilder();
if (serverNamePrefixes != null)
{
buffer.append(serverNamePrefixes[index]);
if (base.equals("saslOption"))
{
buffer.append("SASLOption");
}
else
{
buffer.append(StaticUtils.capitalize(base));
}
}
else
{
buffer.append(base);
}
if (serverNameSuffixes != null)
{
buffer.append(serverNameSuffixes[index]);
}
return buffer.toString();
}
/**
* Constructs the name to use for an argument from the given base and the
* appropriate prefix and suffix. In this case, dashes will be used to
* separate words rather than capitalization.
*
* @param index The index into the set of prefixes and suffixes.
* @param base The base name for the argument.
*
* @return The constructed argument name.
*/
@NotNull()
private String genDashedArgName(final int index, @NotNull final String base)
{
final StringBuilder buffer = new StringBuilder();
if (serverNamePrefixes != null)
{
buffer.append(serverNamePrefixes[index]);
buffer.append('-');
}
buffer.append(base);
if (serverNameSuffixes != null)
{
buffer.append('-');
buffer.append(serverNameSuffixes[index]);
}
return buffer.toString();
}
/**
* Indicates whether the LDAP-specific arguments should include alternate
* versions of all long identifiers that consist of multiple words so that
* they are available in both camelCase and dash-separated versions.
*
* @return {@code true} if this tool should provide multiple versions of
* long identifiers for LDAP-specific arguments, or {@code false} if
* not.
*/
protected boolean includeAlternateLongIdentifiers()
{
return false;
}
/**
* Adds the arguments needed by this command-line tool to the provided
* argument parser which are not related to connecting or authenticating to
* the directory server.
*
* @param parser The argument parser to which the arguments should be added.
*
* @throws ArgumentException If a problem occurs while adding the arguments.
*/
public abstract void addNonLDAPArguments(@NotNull ArgumentParser parser)
throws ArgumentException;
/**
* {@inheritDoc}
*/
@Override()
public final void doExtendedArgumentValidation()
throws ArgumentException
{
doExtendedNonLDAPArgumentValidation();
}
/**
* Performs any necessary processing that should be done to ensure that the
* provided set of command-line arguments were valid. This method will be
* called after the basic argument parsing has been performed and after all
* LDAP-specific argument validation has been processed, and immediately
* before the {@link CommandLineTool#doToolProcessing} method is invoked.
*
* @throws ArgumentException If there was a problem with the command-line
* arguments provided to this program.
*/
public void doExtendedNonLDAPArgumentValidation()
throws ArgumentException
{
// No processing will be performed by default.
}
/**
* Retrieves the connection options that should be used for connections that
* are created with this command line tool. Subclasses may override this
* method to use a custom set of connection options.
*
* @return The connection options that should be used for connections that
* are created with this command line tool.
*/
@NotNull()
public LDAPConnectionOptions getConnectionOptions()
{
return new LDAPConnectionOptions();
}
/**
* Retrieves a connection that may be used to communicate with the indicated
* directory server.
*
* Note that this method is threadsafe and may be invoked by multiple threads
* accessing the same instance only while that instance is in the process of
* invoking the {@link #doToolProcessing} method.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
*
* @return A connection that may be used to communicate with the indicated
* directory server.
*
* @throws LDAPException If a problem occurs while creating the connection.
*/
@ThreadSafety(level=ThreadSafetyLevel.METHOD_THREADSAFE)
@NotNull()
public final LDAPConnection getConnection(final int serverIndex)
throws LDAPException
{
final LDAPConnection connection = getUnauthenticatedConnection(serverIndex);
try
{
if (bindRequest[serverIndex] != null)
{
connection.bind(bindRequest[serverIndex]);
}
}
catch (final LDAPException le)
{
Debug.debugException(le);
connection.close();
throw le;
}
return connection;
}
/**
* Retrieves an unauthenticated connection that may be used to communicate
* with the indicated directory server.
*
* Note that this method is threadsafe and may be invoked by multiple threads
* accessing the same instance only while that instance is in the process of
* invoking the {@link #doToolProcessing} method.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
*
* @return An unauthenticated connection that may be used to communicate with
* the indicated directory server.
*
* @throws LDAPException If a problem occurs while creating the connection.
*/
@ThreadSafety(level=ThreadSafetyLevel.METHOD_THREADSAFE)
@NotNull()
public final LDAPConnection getUnauthenticatedConnection(
final int serverIndex)
throws LDAPException
{
if (serverSet[serverIndex] == null)
{
serverSet[serverIndex] = createServerSet(serverIndex);
bindRequest[serverIndex] = createBindRequest(serverIndex);
}
final LDAPConnection connection = serverSet[serverIndex].getConnection();
if (useStartTLS[serverIndex].isPresent())
{
try
{
final ExtendedResult extendedResult =
connection.processExtendedOperation(new StartTLSExtendedRequest(
startTLSSocketFactory[serverIndex]));
if (! extendedResult.getResultCode().equals(ResultCode.SUCCESS))
{
throw new LDAPException(extendedResult.getResultCode(),
ERR_LDAP_TOOL_START_TLS_FAILED.get(
extendedResult.getDiagnosticMessage()));
}
}
catch (final LDAPException le)
{
Debug.debugException(le);
connection.close();
throw le;
}
}
return connection;
}
/**
* Retrieves a connection pool that may be used to communicate with the
* indicated directory server.
*
* Note that this method is threadsafe and may be invoked by multiple threads
* accessing the same instance only while that instance is in the process of
* invoking the {@link #doToolProcessing} method.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
* @param initialConnections The number of connections that should be
* initially established in the pool.
* @param maxConnections The maximum number of connections to maintain
* in the pool.
*
* @return A connection that may be used to communicate with the indicated
* directory server.
*
* @throws LDAPException If a problem occurs while creating the connection
* pool.
*/
@ThreadSafety(level=ThreadSafetyLevel.METHOD_THREADSAFE)
@NotNull()
public final LDAPConnectionPool getConnectionPool(
final int serverIndex,
final int initialConnections,
final int maxConnections)
throws LDAPException
{
if (serverSet[serverIndex] == null)
{
serverSet[serverIndex] = createServerSet(serverIndex);
bindRequest[serverIndex] = createBindRequest(serverIndex);
}
PostConnectProcessor postConnectProcessor = null;
if (useStartTLS[serverIndex].isPresent())
{
postConnectProcessor = new StartTLSPostConnectProcessor(
startTLSSocketFactory[serverIndex]);
}
return new LDAPConnectionPool(serverSet[serverIndex],
bindRequest[serverIndex], initialConnections, maxConnections,
postConnectProcessor);
}
/**
* Creates the server set to use when creating connections or connection
* pools.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
*
* @return The server set to use when creating connections or connection
* pools.
*
* @throws LDAPException If a problem occurs while creating the server set.
*/
@NotNull()
public final ServerSet createServerSet(final int serverIndex)
throws LDAPException
{
final SSLUtil sslUtil = createSSLUtil(serverIndex);
SocketFactory socketFactory = null;
if (useSSL[serverIndex].isPresent())
{
try
{
socketFactory = sslUtil.createSSLSocketFactory();
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_CREATE_SSL_SOCKET_FACTORY.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
else if (useStartTLS[serverIndex].isPresent())
{
try
{
startTLSSocketFactory[serverIndex] = sslUtil.createSSLSocketFactory();
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_CREATE_SSL_SOCKET_FACTORY.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
return new SingleServerSet(host[serverIndex].getValue(),
port[serverIndex].getValue(), socketFactory, getConnectionOptions());
}
/**
* Creates the SSLUtil instance to use for secure communication.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
*
* @return The SSLUtil instance to use for secure communication, or
* {@code null} if secure communication is not needed.
*
* @throws LDAPException If a problem occurs while creating the SSLUtil
* instance.
*/
@Nullable()
public final SSLUtil createSSLUtil(final int serverIndex)
throws LDAPException
{
if (useSSL[serverIndex].isPresent() || useStartTLS[serverIndex].isPresent())
{
KeyManager keyManager = null;
if (keyStorePath[serverIndex].isPresent())
{
char[] pw = null;
if (keyStorePassword[serverIndex].isPresent())
{
pw = keyStorePassword[serverIndex].getValue().toCharArray();
}
else if (keyStorePasswordFile[serverIndex].isPresent())
{
try
{
pw = getPasswordFileReader().readPassword(
keyStorePasswordFile[serverIndex].getValue());
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_READ_KEY_STORE_PASSWORD.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
try
{
keyManager = new KeyStoreKeyManager(
keyStorePath[serverIndex].getValue(), pw,
keyStoreFormat[serverIndex].getValue(),
certificateNickname[serverIndex].getValue(), true);
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_CREATE_KEY_MANAGER.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
TrustManager tm;
if (trustAll[serverIndex].isPresent())
{
tm = new TrustAllTrustManager(false);
}
else if (trustStorePath[serverIndex].isPresent())
{
char[] pw = null;
if (trustStorePassword[serverIndex].isPresent())
{
pw = trustStorePassword[serverIndex].getValue().toCharArray();
}
else if (trustStorePasswordFile[serverIndex].isPresent())
{
try
{
pw = getPasswordFileReader().readPassword(
trustStorePasswordFile[serverIndex].getValue());
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_READ_TRUST_STORE_PASSWORD.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
final TrustStoreTrustManager trustStoreTrustManager =
new TrustStoreTrustManager(trustStorePath[serverIndex].getValue(),
pw, trustStoreFormat[serverIndex].getValue(), true);
if (defaultTrust[serverIndex].isPresent())
{
tm = InternalSDKHelper.getPreferredNonInteractiveTrustManagerChain(
trustStoreTrustManager);
}
else
{
tm = trustStoreTrustManager;
}
}
else if (defaultTrust[serverIndex].isPresent())
{
tm = InternalSDKHelper.getPreferredNonInteractiveTrustManagerChain();
}
else
{
tm = promptTrustManager.get();
if (tm == null)
{
final AggregateTrustManager atm =
InternalSDKHelper.getPreferredPromptTrustManagerChain(null);
if (promptTrustManager.compareAndSet(null, atm))
{
tm = atm;
}
else
{
tm = promptTrustManager.get();
}
}
}
return new SSLUtil(keyManager, tm);
}
else
{
return null;
}
}
/**
* Creates the bind request to use to authenticate to the indicated server.
*
* @param serverIndex The zero-based index of the server to which the
* connection should be established.
*
* @return The bind request to use to authenticate to the indicated server,
* or {@code null} if no bind should be performed.
*
* @throws LDAPException If a problem occurs while creating the bind
* request.
*/
@Nullable()
public final BindRequest createBindRequest(final int serverIndex)
throws LDAPException
{
final String pw;
if (bindPassword[serverIndex].isPresent())
{
pw = bindPassword[serverIndex].getValue();
}
else if (bindPasswordFile[serverIndex].isPresent())
{
try
{
pw = new String(getPasswordFileReader().readPassword(
bindPasswordFile[serverIndex].getValue()));
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.LOCAL_ERROR,
ERR_LDAP_TOOL_CANNOT_READ_BIND_PASSWORD.get(
StaticUtils.getExceptionMessage(e)), e);
}
}
else
{
pw = null;
}
if (saslOption[serverIndex].isPresent())
{
final String dnStr;
if (bindDN[serverIndex].isPresent())
{
dnStr = bindDN[serverIndex].getValue().toString();
}
else
{
dnStr = null;
}
return SASLUtils.createBindRequest(dnStr, pw, null,
saslOption[serverIndex].getValues());
}
else if (bindDN[serverIndex].isPresent())
{
return new SimpleBindRequest(bindDN[serverIndex].getValue(), pw);
}
else
{
return null;
}
}
}