| | |
| | | |
| | | |
| | | |
| | | import static org.opends.server.loggers.Access.logConnect; |
| | | import static org.opends.server.loggers.Error.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.messages.MessageHandler.getMessage; |
| | | import static org.opends.server.messages.ProtocolMessages.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | |
| | | import java.net.InetAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.net.UnknownHostException; |
| | | import java.nio.channels.SelectionKey; |
| | | import java.nio.channels.Selector; |
| | | import java.nio.channels.ServerSocketChannel; |
| | | import java.nio.channels.SocketChannel; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.server.LDAPConnectionHandlerCfg; |
| | | import org.opends.server.api.AlertGenerator; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.ConfigurableComponent; |
| | | import org.opends.server.api.ConnectionHandler; |
| | | import org.opends.server.api.ConnectionSecurityProvider; |
| | | import org.opends.server.api.KeyManagerProvider; |
| | | import org.opends.server.api.ServerShutdownListener; |
| | | import org.opends.server.api.TrustManagerProvider; |
| | | import org.opends.server.api.plugin.PostConnectPluginResult; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.PluginConfigManager; |
| | | import org.opends.server.config.BooleanConfigAttribute; |
| | | import org.opends.server.config.ConfigAttribute; |
| | | import org.opends.server.config.ConfigEntry; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.config.DNConfigAttribute; |
| | | import org.opends.server.config.IntegerConfigAttribute; |
| | | import org.opends.server.config.IntegerWithUnitConfigAttribute; |
| | | import org.opends.server.config.MultiChoiceConfigAttribute; |
| | | import org.opends.server.config.StringConfigAttribute; |
| | | import org.opends.server.extensions.NullConnectionSecurityProvider; |
| | | import org.opends.server.extensions.TLSConnectionSecurityProvider; |
| | | import org.opends.server.types.AddressMask; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.DisconnectReason; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DisconnectReason; |
| | | import org.opends.server.types.ErrorLogCategory; |
| | | import org.opends.server.types.ErrorLogSeverity; |
| | | import org.opends.server.types.HostPort; |
| | |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SSLClientAuthPolicy; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.Access.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import static org.opends.server.loggers.Error.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | | import static org.opends.server.messages.ProtocolMessages.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a connection handler that will be used for communicating |
| | | * with clients over LDAP. It is actually implemented in two parts: as a |
| | | * connection handler and one or more request handlers. The connection handler |
| | | * is responsible for accepting new connections and registering each of them |
| | | * with a request handler. The request handlers then are responsible for |
| | | * reading requests from the clients and parsing them as operations. A single |
| | | * request handler may be used, but having multiple handlers might provide |
| | | * This class defines a connection handler that will be used for |
| | | * communicating with clients over LDAP. It is actually implemented in |
| | | * two parts: as a connection handler and one or more request |
| | | * handlers. The connection handler is responsible for accepting new |
| | | * connections and registering each of them with a request handler. |
| | | * The request handlers then are responsible for reading requests from |
| | | * the clients and parsing them as operations. A single request |
| | | * handler may be used, but having multiple handlers might provide |
| | | * better performance in a multi-CPU system. |
| | | */ |
| | | public class LDAPConnectionHandler |
| | | extends ConnectionHandler |
| | | implements ConfigurableComponent, AlertGenerator |
| | | { |
| | | public final class LDAPConnectionHandler extends |
| | | ConnectionHandler<LDAPConnectionHandlerCfg> implements |
| | | ConfigurationChangeListener<LDAPConnectionHandlerCfg>, |
| | | ServerShutdownListener, AlertGenerator { |
| | | |
| | | /** |
| | | * The fully-qualified name of this class. |
| | | */ |
| | | private static final String CLASS_NAME = |
| | | "org.opends.server.protocols.ldap.LDAPConnectionHandler"; |
| | | "org.opends.server.protocols.ldap.LDAPConnectionHandler"; |
| | | |
| | | // The current configuration state. |
| | | private LDAPConnectionHandlerCfg currentConfig; |
| | | |
| | | |
| | | /** |
| | | * The hash map that holds the units that may be provided in conjunction with |
| | | * the maximum request size. |
| | | */ |
| | | private static final HashMap<String,Double> SIZE_UNITS = |
| | | new HashMap<String,Double>(); |
| | | |
| | | static |
| | | { |
| | | SIZE_UNITS.put(SIZE_UNIT_BYTES_ABBR, 1D); |
| | | SIZE_UNITS.put(SIZE_UNIT_BYTES_FULL, 1D); |
| | | SIZE_UNITS.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_KILOBYTES_FULL, 1000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D); |
| | | SIZE_UNITS.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D); |
| | | SIZE_UNITS.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D); |
| | | SIZE_UNITS.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024)); |
| | | SIZE_UNITS.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024)); |
| | | SIZE_UNITS.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024)); |
| | | SIZE_UNITS.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The maximum value that may be specified for the max request size |
| | | * configuration attribute. |
| | | */ |
| | | private static final int MAX_REQUEST_SIZE_LIMIT = 2147483647; |
| | | |
| | | |
| | | |
| | | // The set of clients that are explicitly allowed access to the server. |
| | | private AddressMask[] allowedClients; |
| | | |
| | | // The set of clients that have been explicitly denied access to the server. |
| | | private AddressMask[] deniedClients; |
| | | |
| | | // Indicates whether to allow LDAPv2 clients. |
| | | private boolean allowLDAPv2; |
| | | |
| | | // Indicates whether to allow the reuse address socket option. |
| | | private boolean allowReuseAddress; |
| | | |
| | | // Indicates whether to allow startTLS extended operations on this connection. |
| | | private boolean allowStartTLS; |
| | | |
| | | // Indicates whether this connection handler is enabled. |
| | | private boolean enabled; |
| | | |
| | | // Indicates whether usage statistics should be maintained. |
| | | private boolean keepStats; |
| | | |
| | | // Indicates whether the server should send an LDAP notice of disconnection |
| | | // message to a client if a connection is rejected. |
| | | private boolean sendRejectionNotice; |
| | | |
| | | // Indicates whether the Directory Server is in the process of shutting down. |
| | | private boolean shutdownRequested; |
| | | |
| | | // Indicates whether to use TCP keepalive messages for new connections. |
| | | private boolean useKeepAlive; |
| | | |
| | | // Indicates whether to use SSL to communicate with the clients. |
| | | private boolean useSSL; |
| | | |
| | | // Indicates whether to use TCP_NODELAY for new connections. |
| | | private boolean useTCPNoDelay; |
| | | |
| | | // The connection security provider that will be used by default for new |
| | | // client connections. |
| | | private ConnectionSecurityProvider securityProvider; |
| | | |
| | | // The DN of the configuration entry for this connection handler. |
| | | private DN configEntryDN; |
| | | |
| | | // The DN of the key manager provider for this connection handler. |
| | | private DN keyManagerProviderDN; |
| | | |
| | | // The DN of the trust manager provider for this connection handler. |
| | | private DN trustManagerProviderDN; |
| | | /* Properties that cannot be modified dynamically */ |
| | | |
| | | // The set of addresses on which to listen for new connections. |
| | | private HashSet<InetAddress> listenAddresses; |
| | | private Set<InetAddress> listenAddresses; |
| | | |
| | | // The backlog that will be used for the accept queue. |
| | | private int backlog; |
| | | |
| | | // The port on which this connection handler should listen for requests. |
| | | // The port on which this connection handler should listen for |
| | | // requests. |
| | | private int listenPort; |
| | | |
| | | // The maximum ASN.1 element value length that will be allowed when processing |
| | | // requests for this connection handler. |
| | | private int maxRequestSize; |
| | | |
| | | // The number of request handlers that should be used for this connection |
| | | // handler. |
| | | private int numRequestHandlers; |
| | | |
| | | // The index to the request handler that will be used for the next connection |
| | | // accepted by the server. |
| | | private int requestHandlerIndex; |
| | | |
| | | // The set of listeners for this connection handler. |
| | | private LinkedList<HostPort> listeners; |
| | | |
| | | // The set of request handlers that are associated with this connection |
| | | // handler. |
| | | private LDAPRequestHandler[] requestHandlers; |
| | | |
| | | // The set of statistics collected for this connection handler. |
| | | private LDAPStatistics statTracker; |
| | | |
| | | // The selector that will be used to multiplex connection acceptance across |
| | | // multiple sockets by a single thread. |
| | | private Selector selector; |
| | | |
| | | // The SSL client auth policy used by this connection handler. |
| | | private SSLClientAuthPolicy sslClientAuthPolicy; |
| | | |
| | | // The unique name assigned to this connection handler. |
| | | private String handlerName; |
| | | // The backlog that will be used for the accept queue. |
| | | private int backlog; |
| | | |
| | | // The protocol used by this connection handler. |
| | | private String protocol; |
| | | // Indicates whether to allow the reuse address socket option. |
| | | private boolean allowReuseAddress; |
| | | |
| | | // The security mechanism used for connections accepted by this connection |
| | | // handler. |
| | | private String securityMechanism; |
| | | // The number of request handlers that should be used for this |
| | | // connection handler. |
| | | private int numRequestHandlers; |
| | | |
| | | // The nickname of the SSL certificate that should be used if SSL is enabled. |
| | | private String sslServerCertNickname; |
| | | // Indicates whether the Directory Server is in the process of |
| | | // shutting down. |
| | | private boolean shutdownRequested; |
| | | |
| | | /* Internal LDAP connection handler state */ |
| | | |
| | | // Indicates whether this connection handler is enabled. |
| | | private boolean enabled; |
| | | |
| | | // The set of clients that are explicitly allowed access to the |
| | | // server. |
| | | private AddressMask[] allowedClients; |
| | | |
| | | // The set of clients that have been explicitly denied access to the |
| | | // server. |
| | | private AddressMask[] deniedClients; |
| | | |
| | | // The set of SSL cipher suites that should be allowed. |
| | | private String[] enabledSSLCipherSuites; |
| | |
| | | // The set of SSL protocols that should be allowed. |
| | | private String[] enabledSSLProtocols; |
| | | |
| | | // The thread being used to run this connection handler. |
| | | private Thread connHandlerThread; |
| | | // The index to the request handler that will be used for the next |
| | | // connection accepted by the server. |
| | | private int requestHandlerIndex; |
| | | |
| | | // The set of listeners for this connection handler. |
| | | private LinkedList<HostPort> listeners; |
| | | |
| | | // The set of request handlers that are associated with this |
| | | // connection handler. |
| | | private LDAPRequestHandler[] requestHandlers; |
| | | |
| | | // The set of statistics collected for this connection handler. |
| | | private LDAPStatistics statTracker; |
| | | |
| | | // The selector that will be used to multiplex connection acceptance |
| | | // across multiple sockets by a single thread. |
| | | private Selector selector; |
| | | |
| | | // The unique name assigned to this connection handler. |
| | | private String handlerName; |
| | | |
| | | // The protocol used by this connection handler. |
| | | private String protocol; |
| | | |
| | | // The connection security provider that will be used by default for |
| | | // new client connections. |
| | | private ConnectionSecurityProvider securityProvider; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this LDAP connection handler. It must be |
| | | * initialized before it may be used. |
| | | * Creates a new instance of this LDAP connection handler. It must |
| | | * be initialized before it may be used. |
| | | */ |
| | | public LDAPConnectionHandler() |
| | | { |
| | | public LDAPConnectionHandler() { |
| | | super("LDAP Connection Handler Thread"); |
| | | |
| | | |
| | | // No real implementation is required. Do all the work in the |
| | | // No real implementation is required. Do all the work in the |
| | | // initializeConnectionHandler method. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Initializes this connection handler based on the information in the |
| | | * provided configuration entry. |
| | | * Indicates whether this connection handler should allow |
| | | * interaction with LDAPv2 clients. |
| | | * |
| | | * @param configEntry The configuration entry that contains the information |
| | | * to use to initialize this connection handler. |
| | | * |
| | | * @throws ConfigException If there is a problem with the configuration for |
| | | * this connection handler. |
| | | * |
| | | * @throws InitializationException If a problem occurs while attempting to |
| | | * initialize this connection handler. |
| | | * @return <CODE>true</CODE> if LDAPv2 is allowed, or <CODE>false</CODE> |
| | | * if not. |
| | | */ |
| | | public void initializeConnectionHandler(ConfigEntry configEntry) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | enabled = true; |
| | | public boolean allowLDAPv2() { |
| | | return currentConfig.isAllowLDAPV2(); |
| | | } |
| | | |
| | | configEntryDN = configEntry.getDN(); |
| | | |
| | | // Determine the set of addresses on which to listen. There can be |
| | | // multiple addresses specified. |
| | | int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_ADDRESS; |
| | | listenAddresses = new HashSet<InetAddress>(); |
| | | StringConfigAttribute addrStub = |
| | | new StringConfigAttribute(ATTR_LISTEN_ADDRESS, getMessage(msgID), |
| | | true, true, true); |
| | | try |
| | | { |
| | | StringConfigAttribute addrAttr = |
| | | (StringConfigAttribute) configEntry.getConfigAttribute(addrStub); |
| | | if ((addrAttr == null) || addrAttr.activeValues().isEmpty()) |
| | | { |
| | | // This is fine -- we'll just listen on all IPv4 addresses. |
| | | listenAddresses.add(InetAddress.getByName("0.0.0.0")); |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should allow the use of |
| | | * the StartTLS extended operation. |
| | | * |
| | | * @return <CODE>true</CODE> if StartTLS is allowed, or <CODE>false</CODE> |
| | | * if not. |
| | | */ |
| | | public boolean allowStartTLS() { |
| | | if (currentConfig.isAllowStartTLS()) { |
| | | if (currentConfig.isUseSSL()) { |
| | | return false; |
| | | } else { |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | for (String s : addrAttr.activeValues()) |
| | | { |
| | | try |
| | | { |
| | | listenAddresses.add(InetAddress.getByName(s)); |
| | | } |
| | | catch (UnknownHostException uhe) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, uhe); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_UNKNOWN_LISTEN_ADDRESS; |
| | | String message = getMessage(msgID, s, |
| | | stackTraceToSingleLineString(uhe)); |
| | | throw new ConfigException(msgID, message, uhe); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_LISTEN_ADDRESS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the port on which to listen. There may only be a single port |
| | | // specified. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT; |
| | | IntegerConfigAttribute portStub = |
| | | new IntegerConfigAttribute(ATTR_LISTEN_PORT, getMessage(msgID), true, |
| | | false, true, true, 1, true, 65535); |
| | | try |
| | | { |
| | | IntegerConfigAttribute portAttr = |
| | | (IntegerConfigAttribute) configEntry.getConfigAttribute(portStub); |
| | | if (portAttr == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_NO_LISTEN_PORT; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | |
| | | listenPort = portAttr.activeIntValue(); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_LISTEN_PORT; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the accept backlog. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_BACKLOG; |
| | | IntegerConfigAttribute backlogStub = |
| | | new IntegerConfigAttribute(ATTR_ACCEPT_BACKLOG, getMessage(msgID), |
| | | true, false, true, true, 1, true, |
| | | Integer.MAX_VALUE); |
| | | try |
| | | { |
| | | IntegerConfigAttribute backlogAttr = |
| | | (IntegerConfigAttribute) configEntry.getConfigAttribute(backlogStub); |
| | | if (backlogAttr == null) |
| | | { |
| | | // This is fine -- just use the default value. |
| | | backlog = DEFAULT_ACCEPT_BACKLOG; |
| | | } |
| | | else |
| | | { |
| | | backlog = backlogAttr.activeIntValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_BACKLOG; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the set of allowed clients. |
| | | allowedClients = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOWED_CLIENTS; |
| | | StringConfigAttribute allowedStub = |
| | | new StringConfigAttribute(ATTR_ALLOWED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute allowedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(allowedStub); |
| | | if (allowedAttr != null) |
| | | { |
| | | List<String> maskStrings = allowedAttr.activeValues(); |
| | | allowedClients = new AddressMask[maskStrings.size()]; |
| | | for (int i=0; i < allowedClients.length; i++) |
| | | { |
| | | try |
| | | { |
| | | allowedClients[i] = AddressMask.decode(maskStrings.get(i)); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | String message = getMessage(msgID, maskStrings.get(i), |
| | | ATTR_ALLOWED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce)); |
| | | throw new ConfigException(msgID, message, ce); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOWED_CLIENTS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the set of denied clients. |
| | | deniedClients = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_DENIED_CLIENTS; |
| | | StringConfigAttribute deniedStub = |
| | | new StringConfigAttribute(ATTR_DENIED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute deniedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(deniedStub); |
| | | if (deniedAttr != null) |
| | | { |
| | | List<String> maskStrings = deniedAttr.activeValues(); |
| | | deniedClients = new AddressMask[maskStrings.size()]; |
| | | for (int i=0; i < deniedClients.length; i++) |
| | | { |
| | | try |
| | | { |
| | | deniedClients[i] = AddressMask.decode(maskStrings.get(i)); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | String message = getMessage(msgID, maskStrings.get(i), |
| | | ATTR_ALLOWED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce)); |
| | | throw new ConfigException(msgID, message, ce); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_DENIED_CLIENTS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow LDAPv2 clients. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_LDAPV2; |
| | | BooleanConfigAttribute allowLDAPv2Stub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_LDAPV2, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute allowLDAPv2Attr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(allowLDAPv2Stub); |
| | | if (allowLDAPv2Attr == null) |
| | | { |
| | | // This is fine -- we'll just use the default behavior, which is to |
| | | // allow these clients. |
| | | allowLDAPv2 = DEFAULT_ALLOW_LDAPV2; |
| | | } |
| | | else |
| | | { |
| | | allowLDAPv2 = allowLDAPv2Attr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_LDAPV2; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to keep LDAP statistics. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEEP_STATS; |
| | | BooleanConfigAttribute keepStatsStub = |
| | | new BooleanConfigAttribute(ATTR_KEEP_LDAP_STATS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepStatsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepStatsStub); |
| | | if (keepStatsAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default behavior, which is to |
| | | // allow these clients. |
| | | keepStats = DEFAULT_KEEP_LDAP_STATS; |
| | | } |
| | | else |
| | | { |
| | | keepStats = keepStatsAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEEP_STATS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the number of request handlers to maintain. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_NUM_REQUEST_HANDLERS; |
| | | IntegerConfigAttribute reqHandlerStub = |
| | | new IntegerConfigAttribute(ATTR_NUM_REQUEST_HANDLERS, |
| | | getMessage(msgID), true, false, true, |
| | | true, 1, false, 0); |
| | | try |
| | | { |
| | | IntegerConfigAttribute reqHandlerAttr = |
| | | (IntegerConfigAttribute) |
| | | configEntry.getConfigAttribute(reqHandlerStub); |
| | | if (reqHandlerAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default value. |
| | | numRequestHandlers = DEFAULT_NUM_REQUEST_HANDLERS; |
| | | } |
| | | else |
| | | { |
| | | numRequestHandlers = reqHandlerAttr.activeIntValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_NUM_REQUEST_HANDLERS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to send a notice to clients on rejection. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SEND_REJECTION_NOTICE; |
| | | BooleanConfigAttribute notifyRejectsStub = |
| | | new BooleanConfigAttribute(ATTR_SEND_REJECTION_NOTICE, |
| | | getMessage(msgID), false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute notifyRejectsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(notifyRejectsStub); |
| | | if (notifyRejectsAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default value. |
| | | sendRejectionNotice = DEFAULT_SEND_REJECTION_NOTICE; |
| | | } |
| | | else |
| | | { |
| | | sendRejectionNotice = notifyRejectsAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SEND_REJECTION_NOTICE; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP keepalive. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_KEEPALIVE; |
| | | BooleanConfigAttribute keepAliveStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_KEEPALIVE, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepAliveAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepAliveStub); |
| | | if (keepAliveAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | useKeepAlive = DEFAULT_USE_TCP_KEEPALIVE; |
| | | } |
| | | else |
| | | { |
| | | useKeepAlive = keepAliveAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_KEEPALIVE; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP nodelay. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_NODELAY; |
| | | BooleanConfigAttribute noDelayStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_NODELAY, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute noDelayAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(noDelayStub); |
| | | if (noDelayAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | useTCPNoDelay = DEFAULT_USE_TCP_NODELAY; |
| | | } |
| | | else |
| | | { |
| | | useTCPNoDelay = noDelayAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_NODELAY; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow reuse of address/port combinations. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_REUSE_ADDRESS; |
| | | BooleanConfigAttribute reuseAddrStub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_REUSE_ADDRESS, |
| | | getMessage(msgID), true); |
| | | try |
| | | { |
| | | BooleanConfigAttribute reuseAddrAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(reuseAddrStub); |
| | | if (reuseAddrAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | allowReuseAddress = DEFAULT_ALLOW_REUSE_ADDRESS; |
| | | } |
| | | else |
| | | { |
| | | allowReuseAddress = reuseAddrAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_REUSE_ADDRESS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the maximum allowed request size. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_MAX_REQUEST_SIZE; |
| | | IntegerWithUnitConfigAttribute maxReqSizeStub = |
| | | new IntegerWithUnitConfigAttribute(ATTR_MAX_REQUEST_SIZE, |
| | | getMessage(msgID), false, |
| | | SIZE_UNITS, true, 0, true, |
| | | MAX_REQUEST_SIZE_LIMIT); |
| | | try |
| | | { |
| | | IntegerWithUnitConfigAttribute maxReqSizeAttr = |
| | | (IntegerWithUnitConfigAttribute) |
| | | configEntry.getConfigAttribute(maxReqSizeStub); |
| | | if (maxReqSizeAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default value. |
| | | maxRequestSize = DEFAULT_MAX_REQUEST_SIZE; |
| | | } |
| | | else |
| | | { |
| | | maxRequestSize = (int) maxReqSizeAttr.activeCalculatedValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_MAX_REQUEST_SIZE; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to use SSL. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_SSL; |
| | | BooleanConfigAttribute useSSLStub = |
| | | new BooleanConfigAttribute(ATTR_USE_SSL, getMessage(msgID), true); |
| | | try |
| | | { |
| | | BooleanConfigAttribute useSSLAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(useSSLStub); |
| | | if (useSSLAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default value. |
| | | useSSL = DEFAULT_USE_SSL; |
| | | } |
| | | else |
| | | { |
| | | useSSL = useSSLAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_SSL; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow the StartTLS extended operation. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS; |
| | | BooleanConfigAttribute startTLSStub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute startTLSAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(startTLSStub); |
| | | if (startTLSAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | allowStartTLS = DEFAULT_ALLOW_STARTTLS; |
| | | } |
| | | else |
| | | { |
| | | allowStartTLS = startTLSAttr.activeValue(); |
| | | } |
| | | |
| | | |
| | | // See if both SSL and startTLS are configured. If so, we'll have to |
| | | // disable startTLS because they can't both be used concurrently. |
| | | if (useSSL && allowStartTLS) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_HAVE_SSL_AND_STARTTLS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN)); |
| | | logError(ErrorLogCategory.CONFIGURATION, |
| | | ErrorLogSeverity.SEVERE_WARNING, message, msgID); |
| | | |
| | | allowStartTLS = false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_STARTTLS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine how to handle SSL client authentication. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CLIENT_AUTH_POLICY; |
| | | HashSet<String> allowedValues = new HashSet<String>(3); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.DISABLED.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.OPTIONAL.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.REQUIRED.toString())); |
| | | MultiChoiceConfigAttribute sslAuthPolicyStub = |
| | | new MultiChoiceConfigAttribute(ATTR_SSL_CLIENT_AUTH_POLICY, |
| | | getMessage(msgID), false, false, true, |
| | | allowedValues); |
| | | try |
| | | { |
| | | MultiChoiceConfigAttribute sslAuthPolicyAttr = |
| | | (MultiChoiceConfigAttribute) |
| | | configEntry.getConfigAttribute(sslAuthPolicyStub); |
| | | if (sslAuthPolicyAttr == null) |
| | | { |
| | | // This is fine -- We'll just use the default. |
| | | sslClientAuthPolicy = DEFAULT_SSL_CLIENT_AUTH_POLICY; |
| | | } |
| | | else |
| | | { |
| | | sslClientAuthPolicy = SSLClientAuthPolicy.policyForName( |
| | | sslAuthPolicyAttr.activeValue()); |
| | | if (sslClientAuthPolicy == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_SSL_CLIENT_AUTH_POLICY; |
| | | String message = getMessage(msgID, sslAuthPolicyAttr.activeValue(), |
| | | String.valueOf(configEntryDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CLIENT_AUTH_POLICY; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine which SSL certificate to use. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME; |
| | | StringConfigAttribute certNameStub = |
| | | new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME, getMessage(msgID), |
| | | false, false, true); |
| | | try |
| | | { |
| | | StringConfigAttribute certNameAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(certNameStub); |
| | | if (certNameAttr == null) |
| | | { |
| | | // This is fine -- We'll just let the server pick one. |
| | | sslServerCertNickname = null; |
| | | } |
| | | else |
| | | { |
| | | sslServerCertNickname = certNameAttr.activeValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CERT_NICKNAME; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the set of SSL protocols to allow. |
| | | enabledSSLProtocols = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_PROTOCOLS; |
| | | StringConfigAttribute sslProtocolsStub = |
| | | new StringConfigAttribute(ATTR_SSL_PROTOCOLS, getMessage(msgID), false, |
| | | true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslProtocolsAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslProtocolsStub); |
| | | if (sslProtocolsAttr != null) |
| | | { |
| | | enabledSSLProtocols = listToArray(sslProtocolsAttr.activeValues()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_PROTOCOLS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the set of SSL cipher suites to allow. |
| | | enabledSSLCipherSuites = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_CIPHERS; |
| | | StringConfigAttribute sslCiphersStub = |
| | | new StringConfigAttribute(ATTR_SSL_CIPHERS, getMessage(msgID), false, |
| | | true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslCiphersAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslCiphersStub); |
| | | if (sslCiphersAttr != null) |
| | | { |
| | | enabledSSLCipherSuites = listToArray(sslCiphersAttr.activeValues()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CIPHERS; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the key manager provider to use. |
| | | keyManagerProviderDN = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN; |
| | | DNConfigAttribute keyManagerStub = |
| | | new DNConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute keyManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(keyManagerStub); |
| | | if (keyManagerAttr != null) |
| | | { |
| | | keyManagerProviderDN = keyManagerAttr.activeValue(); |
| | | KeyManagerProvider provider = |
| | | DirectoryServer.getKeyManagerProvider(keyManagerProviderDN); |
| | | if (provider == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_KEYMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(keyManagerProviderDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEYMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Determine the trust manager provider to use. |
| | | trustManagerProviderDN = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN; |
| | | DNConfigAttribute trustManagerStub = |
| | | new DNConfigAttribute(ATTR_TRUSTMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute trustManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(trustManagerStub); |
| | | if (trustManagerAttr != null) |
| | | { |
| | | trustManagerProviderDN = trustManagerAttr.activeValue(); |
| | | TrustManagerProvider provider = |
| | | DirectoryServer.getTrustManagerProvider(trustManagerProviderDN); |
| | | if (provider == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_TRUSTMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(trustManagerProviderDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_TRUSTMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | if (useSSL) |
| | | { |
| | | TLSConnectionSecurityProvider tlsProvider = |
| | | new TLSConnectionSecurityProvider(); |
| | | tlsProvider.initializeConnectionSecurityProvider(null); |
| | | tlsProvider.setSSLClientAuthPolicy(sslClientAuthPolicy); |
| | | tlsProvider.setEnabledProtocols(enabledSSLProtocols); |
| | | tlsProvider.setEnabledCipherSuites(enabledSSLCipherSuites); |
| | | |
| | | // FIXME -- Need to do something with the requested cert nickname. |
| | | |
| | | securityProvider = tlsProvider; |
| | | } |
| | | else |
| | | { |
| | | securityProvider = new NullConnectionSecurityProvider(); |
| | | securityProvider.initializeConnectionSecurityProvider(null); |
| | | } |
| | | |
| | | |
| | | DirectoryServer.registerConfigurableComponent(this); |
| | | |
| | | |
| | | try |
| | | { |
| | | selector = Selector.open(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_OPEN_SELECTOR_FAILED; |
| | | String message = getMessage(msgID, configEntryDN, |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | |
| | | // Construct a unique name for this connection handler, and put together the |
| | | // set of listeners. |
| | | listeners = new LinkedList<HostPort>(); |
| | | StringBuilder nameBuffer = new StringBuilder(); |
| | | nameBuffer.append("LDAP Connection Handler"); |
| | | for (InetAddress a : listenAddresses) |
| | | { |
| | | listeners.add(new HostPort(a.getHostAddress(), listenPort)); |
| | | nameBuffer.append(" "); |
| | | nameBuffer.append(a.getHostAddress()); |
| | | } |
| | | nameBuffer.append(" port "); |
| | | nameBuffer.append(listenPort); |
| | | handlerName = nameBuffer.toString(); |
| | | |
| | | |
| | | // Set the security mechanism for this connection handler. |
| | | if (useSSL) |
| | | { |
| | | securityMechanism = SECURITY_MECHANISM_SSL; |
| | | protocol = "LDAP+SSL"; |
| | | } |
| | | else |
| | | { |
| | | securityMechanism = null; |
| | | protocol = "LDAP"; |
| | | } |
| | | |
| | | |
| | | // Perform any additional initialization that might be required. |
| | | connHandlerThread = null; |
| | | statTracker = new LDAPStatistics(handlerName + " Statistics"); |
| | | |
| | | |
| | | // Create and start the request handlers. |
| | | requestHandlers = new LDAPRequestHandler[numRequestHandlers]; |
| | | for (int i=0; i < numRequestHandlers; i++) |
| | | { |
| | | requestHandlers[i] = new LDAPRequestHandler(this, i); |
| | | } |
| | | for (int i=0; i < numRequestHandlers; i++) |
| | | { |
| | | requestHandlers[i].start(); |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Closes this connection handler so that it will no longer accept new client |
| | | * connections. It may or may not disconnect existing client connections |
| | | * based on the provided flag. Note, however, that some connection handler |
| | | * implementations may not have any way to continue processing requests from |
| | | * existing connections, in which case they should always be closed regardless |
| | | * of the value of the <CODE>closeConnections</CODE> flag. |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationChange( |
| | | LDAPConnectionHandlerCfg config) { |
| | | // Create variables to include in the response. |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | // Note that the following properties cannot be modified: |
| | | // |
| | | // * listen port and addresses |
| | | // * use ssl |
| | | // * ssl policy |
| | | // * ssl cert nickname |
| | | // * accept backlog |
| | | // * tcp reuse address |
| | | // * num request handler |
| | | |
| | | // Start/clear the stat tracker if LDAPv2 is being enabled. |
| | | if (currentConfig.isAllowLDAPV2() != config.isAllowLDAPV2()) { |
| | | if (config.isAllowLDAPV2()) { |
| | | if (statTracker == null) { |
| | | statTracker = new LDAPStatistics(handlerName |
| | | + " Statistics"); |
| | | } else { |
| | | statTracker.clearStatistics(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Apply the changes. |
| | | currentConfig = config; |
| | | enabled = config.isEnabled(); |
| | | allowedClients = config.getAllowedClients().toArray( |
| | | new AddressMask[0]); |
| | | deniedClients = config.getDeniedClients().toArray( |
| | | new AddressMask[0]); |
| | | |
| | | // Get the supported SSL ciphers and protocols. |
| | | Set<String> ciphers = config.getSSLCipherSuites(); |
| | | if (ciphers.isEmpty()) { |
| | | enabledSSLCipherSuites = null; |
| | | } else { |
| | | enabledSSLCipherSuites = ciphers.toArray(new String[0]); |
| | | } |
| | | |
| | | Set<String> protocols = config.getSSLProtocols(); |
| | | if (protocols.isEmpty()) { |
| | | enabledSSLProtocols = null; |
| | | } else { |
| | | enabledSSLProtocols = protocols.toArray(new String[0]); |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, |
| | | messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Closes this connection handler so that it will no longer accept |
| | | * new client connections. It may or may not disconnect existing |
| | | * client connections based on the provided flag. Note, however, |
| | | * that some connection handler implementations may not have any way |
| | | * to continue processing requests from existing connections, in |
| | | * which case they should always be closed regardless of the value |
| | | * of the <CODE>closeConnections</CODE> flag. |
| | | * |
| | | * @param finalizeReason The reason that this connection handler should be |
| | | * finalized. |
| | | * @param closeConnections Indicates whether any established client |
| | | * connections associated with the connection |
| | | * handler should also be closed. |
| | | * @param finalizeReason |
| | | * The reason that this connection handler should be |
| | | * finalized. |
| | | * @param closeConnections |
| | | * Indicates whether any established client connections |
| | | * associated with the connection handler should also be |
| | | * closed. |
| | | */ |
| | | public void finalizeConnectionHandler(String finalizeReason, |
| | | boolean closeConnections) |
| | | { |
| | | boolean closeConnections) { |
| | | shutdownRequested = true; |
| | | currentConfig.removeLDAPChangeListener(this); |
| | | |
| | | DirectoryServer.deregisterConfigurableComponent(this); |
| | | |
| | | try |
| | | { |
| | | try { |
| | | selector.wakeup(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (closeConnections) |
| | | { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) |
| | | { |
| | | if (closeConnections) { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) { |
| | | requestHandler.processServerShutdown(finalizeReason); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) |
| | | { |
| | | } else { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) { |
| | | requestHandler.registerShutdownListener(); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getConnectionHandlerName() |
| | | { |
| | | return handlerName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getProtocol() |
| | | { |
| | | return protocol; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<HostPort> getListeners() |
| | | { |
| | | return listeners; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of active client connections that have been established |
| | | * through this connection handler. |
| | | * Retrieves information about the set of alerts that this generator |
| | | * may produce. The map returned should be between the notification |
| | | * type for a particular notification and the human-readable |
| | | * description for that notification. This alert generator must not |
| | | * generate any alerts with types that are not contained in this |
| | | * list. |
| | | * |
| | | * @return The set of active client connections that have been established |
| | | * through this connection handler. |
| | | * @return Information about the set of alerts that this generator |
| | | * may produce. |
| | | */ |
| | | public Collection<ClientConnection> getClientConnections() |
| | | { |
| | | public LinkedHashMap<String, String> getAlerts() { |
| | | LinkedHashMap<String, String> alerts = new LinkedHashMap<String, String>(); |
| | | |
| | | alerts |
| | | .put(ALERT_TYPE_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, |
| | | ALERT_DESCRIPTION_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES); |
| | | alerts.put(ALERT_TYPE_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR, |
| | | ALERT_DESCRIPTION_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR); |
| | | |
| | | return alerts; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the fully-qualified name of the Java class for this |
| | | * alert generator implementation. |
| | | * |
| | | * @return The fully-qualified name of the Java class for this alert |
| | | * generator implementation. |
| | | */ |
| | | public String getClassName() { |
| | | return CLASS_NAME; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of active client connections that have been |
| | | * established through this connection handler. |
| | | * |
| | | * @return The set of active client connections that have been |
| | | * established through this connection handler. |
| | | */ |
| | | public Collection<ClientConnection> getClientConnections() { |
| | | LinkedList<ClientConnection> connectionList = |
| | | new LinkedList<ClientConnection>(); |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) |
| | | { |
| | | new LinkedList<ClientConnection>(); |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) { |
| | | connectionList.addAll(requestHandler.getClientConnections()); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the configuration entry with which this alert |
| | | * generator is associated. |
| | | * |
| | | * @return The DN of the configuration entry with which this alert |
| | | * generator is associated. |
| | | */ |
| | | public DN getComponentEntryDN() { |
| | | return currentConfig.dn(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getConnectionHandlerName() { |
| | | return handlerName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of enabled SSL cipher suites configured for |
| | | * this connection handler. |
| | | * |
| | | * @return The set of enabled SSL cipher suites configured for this |
| | | * connection handler. |
| | | */ |
| | | public String[] getEnabledSSLCipherSuites() { |
| | | return enabledSSLCipherSuites; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of enabled SSL protocols configured for this |
| | | * connection handler. |
| | | * |
| | | * @return The set of enabled SSL protocols configured for this |
| | | * connection handler. |
| | | */ |
| | | public String[] getEnabledSSLProtocols() { |
| | | return enabledSSLProtocols; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the key manager provider that should be used |
| | | * for operations associated with this connection handler which need |
| | | * access to a key manager. |
| | | * |
| | | * @return The DN of the key manager provider that should be used |
| | | * for operations associated with this connection handler |
| | | * which need access to a key manager, or {@code null} if no |
| | | * key manager provider has been configured for this |
| | | * connection handler. |
| | | */ |
| | | public DN getKeyManagerProviderDN() { |
| | | return currentConfig.getKeyManagerProviderDN(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<HostPort> getListeners() { |
| | | return listeners; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the port on which this connection handler is listening |
| | | * for client connections. |
| | | * |
| | | * @return The port on which this connection handler is listening |
| | | * for client connections. |
| | | * @return The port on which this connection handler is listening |
| | | * for client connections. |
| | | */ |
| | | public int getListenPort() |
| | | { |
| | | public int getListenPort() { |
| | | return listenPort; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Operates in a loop, accepting new connections and ensuring that requests on |
| | | * those connections are handled properly. |
| | | * Retrieves the maximum ASN.1 element value length that will be |
| | | * allowed by this connection handler. |
| | | * |
| | | * @return The maximum ASN.1 element value length that will be |
| | | * allowed by this connection handler. |
| | | */ |
| | | public void run() |
| | | { |
| | | connHandlerThread = Thread.currentThread(); |
| | | setName(handlerName); |
| | | public int getMaxRequestSize() { |
| | | return (int) ((long) currentConfig.getMaxRequestSize()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getProtocol() { |
| | | return protocol; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getShutdownListenerName() { |
| | | return handlerName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the nickname of the server certificate that should be |
| | | * used in conjunction with this LDAP connection handler. |
| | | * |
| | | * @return The nickname of the server certificate that should be |
| | | * used in conjunction with this LDAP connection handler. |
| | | */ |
| | | public String getSSLServerCertNickname() { |
| | | return currentConfig.getSSLCertNickname(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the SSL client authentication policy for this |
| | | * connection handler. |
| | | * |
| | | * @return The SSL client authentication policy for this connection |
| | | * handler. |
| | | */ |
| | | public SSLClientAuthPolicy getSSLClientAuthPolicy() { |
| | | return sslClientAuthPolicy; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of statistics maintained by this connection |
| | | * handler. |
| | | * |
| | | * @return The set of statistics maintained by this connection |
| | | * handler. |
| | | */ |
| | | public LDAPStatistics getStatTracker() { |
| | | return statTracker; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the trust manager provider that should be |
| | | * used for operations associated with this connection handler which |
| | | * need access to a trust manager. |
| | | * |
| | | * @return The DN of the trust manager provider that should be used |
| | | * for operations associated with this connection handler |
| | | * which need access to a trust manager, or {@code null} if |
| | | * no trust manager provider has been configured for this |
| | | * connection handler. |
| | | */ |
| | | public DN getTrustManagerProviderDN() { |
| | | return currentConfig.getTrustManagerProviderDN(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void initializeConnectionHandler( |
| | | LDAPConnectionHandlerCfg config) |
| | | throws ConfigException, InitializationException { |
| | | // SSL and StartTLS are mutually exclusive. |
| | | if (config.isAllowStartTLS() && config.isUseSSL()) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_CANNOT_HAVE_SSL_AND_STARTTLS; |
| | | String message = getMessage(msgID, String.valueOf(config.dn())); |
| | | logError(ErrorLogCategory.CONFIGURATION, |
| | | ErrorLogSeverity.SEVERE_WARNING, message, msgID); |
| | | } |
| | | |
| | | // Validate the key manager provider DN. |
| | | DN keyManagerProviderDN = config.getKeyManagerProviderDN(); |
| | | if (keyManagerProviderDN != null) { |
| | | KeyManagerProvider provider = DirectoryServer |
| | | .getKeyManagerProvider(keyManagerProviderDN); |
| | | if (provider == null) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_INVALID_KEYMANAGER_DN; |
| | | String message = getMessage(msgID, String |
| | | .valueOf(config.dn()), String |
| | | .valueOf(keyManagerProviderDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | |
| | | // Validate the trust manager provider DN. |
| | | DN trustManagerProviderDN = config.getTrustManagerProviderDN(); |
| | | if (trustManagerProviderDN != null) { |
| | | TrustManagerProvider provider = DirectoryServer |
| | | .getTrustManagerProvider(trustManagerProviderDN); |
| | | if (provider == null) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_INVALID_TRUSTMANAGER_DN; |
| | | String message = getMessage(msgID, String |
| | | .valueOf(config.dn()), String |
| | | .valueOf(trustManagerProviderDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | |
| | | // Open the selector. |
| | | try { |
| | | selector = Selector.open(); |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | int msgID = MSGID_LDAP_CONNHANDLER_OPEN_SELECTOR_FAILED; |
| | | String message = getMessage(msgID, config.dn(), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | // Get the SSL auth policy. |
| | | switch (config.getSSLClientAuthPolicy()) { |
| | | case DISABLED: |
| | | sslClientAuthPolicy = SSLClientAuthPolicy.DISABLED; |
| | | break; |
| | | case REQUIRED: |
| | | sslClientAuthPolicy = SSLClientAuthPolicy.REQUIRED; |
| | | break; |
| | | default: |
| | | sslClientAuthPolicy = SSLClientAuthPolicy.OPTIONAL; |
| | | break; |
| | | } |
| | | |
| | | // Get the supported SSL ciphers and protocols. |
| | | Set<String> ciphers = config.getSSLCipherSuites(); |
| | | if (ciphers.isEmpty()) { |
| | | enabledSSLCipherSuites = null; |
| | | } else { |
| | | enabledSSLCipherSuites = ciphers.toArray(new String[0]); |
| | | } |
| | | |
| | | Set<String> protocols = config.getSSLProtocols(); |
| | | if (protocols.isEmpty()) { |
| | | enabledSSLProtocols = null; |
| | | } else { |
| | | enabledSSLProtocols = protocols.toArray(new String[0]); |
| | | } |
| | | |
| | | // Initialize the security provider. |
| | | if (config.isUseSSL()) { |
| | | TLSConnectionSecurityProvider tlsProvider = |
| | | new TLSConnectionSecurityProvider(); |
| | | tlsProvider.initializeConnectionSecurityProvider(null); |
| | | tlsProvider.setSSLClientAuthPolicy(sslClientAuthPolicy); |
| | | tlsProvider.setEnabledProtocols(enabledSSLProtocols); |
| | | tlsProvider.setEnabledCipherSuites(enabledSSLCipherSuites); |
| | | |
| | | // FIXME -- Need to do something with the requested cert |
| | | // nickname. |
| | | |
| | | securityProvider = tlsProvider; |
| | | } else { |
| | | securityProvider = new NullConnectionSecurityProvider(); |
| | | securityProvider.initializeConnectionSecurityProvider(null); |
| | | } |
| | | |
| | | // Save this configuration for future reference. |
| | | currentConfig = config; |
| | | enabled = config.isEnabled(); |
| | | requestHandlerIndex = 0; |
| | | allowedClients = config.getAllowedClients().toArray( |
| | | new AddressMask[0]); |
| | | deniedClients = config.getDeniedClients().toArray( |
| | | new AddressMask[0]); |
| | | |
| | | // Save properties that cannot be dynamically modified. |
| | | allowReuseAddress = config.isAllowTCPReuseAddress(); |
| | | backlog = config.getAcceptBacklog(); |
| | | listenAddresses = config.getListenAddresses(); |
| | | listenPort = config.getListenPort(); |
| | | numRequestHandlers = config.getNumRequestHandlers(); |
| | | |
| | | // Construct a unique name for this connection handler, and put |
| | | // together the |
| | | // set of listeners. |
| | | listeners = new LinkedList<HostPort>(); |
| | | StringBuilder nameBuffer = new StringBuilder(); |
| | | nameBuffer.append("LDAP Connection Handler"); |
| | | for (InetAddress a : listenAddresses) { |
| | | listeners.add(new HostPort(a.getHostAddress(), listenPort)); |
| | | nameBuffer.append(" "); |
| | | nameBuffer.append(a.getHostAddress()); |
| | | } |
| | | nameBuffer.append(" port "); |
| | | nameBuffer.append(listenPort); |
| | | handlerName = nameBuffer.toString(); |
| | | |
| | | // Set the protocol for this connection handler. |
| | | if (config.isUseSSL()) { |
| | | protocol = "LDAP+SSL"; |
| | | } else { |
| | | protocol = "LDAP"; |
| | | } |
| | | |
| | | // Perform any additional initialization that might be required. |
| | | statTracker = new LDAPStatistics(handlerName + " Statistics"); |
| | | |
| | | // Create and start the request handlers. |
| | | requestHandlers = new LDAPRequestHandler[numRequestHandlers]; |
| | | for (int i = 0; i < numRequestHandlers; i++) { |
| | | requestHandlers[i] = new LDAPRequestHandler(this, i); |
| | | } |
| | | |
| | | for (int i = 0; i < numRequestHandlers; i++) { |
| | | requestHandlers[i].start(); |
| | | } |
| | | |
| | | // Register this as a change listener. |
| | | config.addLDAPChangeListener(this); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationChangeAcceptable( |
| | | LDAPConnectionHandlerCfg config, |
| | | List<String> unacceptableReasons) { |
| | | boolean isAcceptable = true; |
| | | |
| | | // SSL and StartTLS are mutually exclusive. |
| | | if (config.isAllowStartTLS() && config.isUseSSL()) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_CANNOT_HAVE_SSL_AND_STARTTLS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(config |
| | | .dn()))); |
| | | isAcceptable = false; |
| | | } |
| | | |
| | | // Validate the key manager provider DN. |
| | | DN keyManagerProviderDN = config.getKeyManagerProviderDN(); |
| | | if (keyManagerProviderDN != null) { |
| | | KeyManagerProvider provider = DirectoryServer |
| | | .getKeyManagerProvider(keyManagerProviderDN); |
| | | if (provider == null) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_INVALID_KEYMANAGER_DN; |
| | | unacceptableReasons.add(getMessage(msgID, String |
| | | .valueOf(config.dn()), String |
| | | .valueOf(keyManagerProviderDN))); |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | |
| | | // Validate the trust manager provider DN. |
| | | DN trustManagerProviderDN = config.getTrustManagerProviderDN(); |
| | | if (trustManagerProviderDN != null) { |
| | | TrustManagerProvider provider = DirectoryServer |
| | | .getTrustManagerProvider(trustManagerProviderDN); |
| | | if (provider == null) { |
| | | int msgID = MSGID_LDAP_CONNHANDLER_INVALID_TRUSTMANAGER_DN; |
| | | unacceptableReasons.add(getMessage(msgID, String |
| | | .valueOf(config.dn()), String |
| | | .valueOf(trustManagerProviderDN))); |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | |
| | | return isAcceptable; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should maintain usage |
| | | * statistics. |
| | | * |
| | | * @return <CODE>true</CODE> if this connection handler should |
| | | * maintain usage statistics, or <CODE>false</CODE> if |
| | | * not. |
| | | */ |
| | | public boolean keepStats() { |
| | | return currentConfig.isKeepStats(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void processServerShutdown(String reason) { |
| | | shutdownRequested = true; |
| | | |
| | | try { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) { |
| | | try { |
| | | requestHandler.processServerShutdown(reason); |
| | | } catch (Exception e) { |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Operates in a loop, accepting new connections and ensuring that |
| | | * requests on those connections are handled properly. |
| | | */ |
| | | public void run() { |
| | | setName(handlerName); |
| | | boolean listening = false; |
| | | |
| | | while (! shutdownRequested) |
| | | { |
| | | // If this connection handler is not enabled, then just sleep for a bit |
| | | // and check again. |
| | | if (! enabled) |
| | | { |
| | | if (listening) |
| | | { |
| | | while (!shutdownRequested) { |
| | | // If this connection handler is not enabled, then just sleep |
| | | // for a bit and check again. |
| | | if (!enabled) { |
| | | if (listening) { |
| | | cleanUpSelector(); |
| | | listening = false; |
| | | enabled = false; |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.NOTICE, |
| | | MSGID_LDAP_CONNHANDLER_STOPPED_LISTENING, handlerName); |
| | | ErrorLogSeverity.NOTICE, |
| | | MSGID_LDAP_CONNHANDLER_STOPPED_LISTENING, handlerName); |
| | | } |
| | | |
| | | try |
| | | { |
| | | try { |
| | | Thread.sleep(1000); |
| | | } catch (Exception e) {} |
| | | } catch (Exception e) { |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | |
| | | |
| | | // If we have gotten here, then we are about to start listening for the |
| | | // first time since startup or since we were previously disabled. Make |
| | | // sure to start with a clean selector and then create all the listeners. |
| | | try |
| | | { |
| | | // If we have gotten here, then we are about to start listening |
| | | // for the first time since startup or since we were previously |
| | | // disabled. Make sure to start with a clean selector and then |
| | | // create all the listeners. |
| | | try { |
| | | cleanUpSelector(); |
| | | |
| | | int numRegistered = 0; |
| | | for (InetAddress a : listenAddresses) |
| | | { |
| | | try |
| | | { |
| | | for (InetAddress a : listenAddresses) { |
| | | try { |
| | | ServerSocketChannel channel = ServerSocketChannel.open(); |
| | | channel.socket().setReuseAddress(allowReuseAddress); |
| | | channel.socket().bind(new InetSocketAddress(a, listenPort), |
| | | backlog); |
| | | channel.socket().bind( |
| | | new InetSocketAddress(a, listenPort), backlog); |
| | | channel.configureBlocking(false); |
| | | channel.register(selector, SelectionKey.OP_ACCEPT); |
| | | numRegistered++; |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.NOTICE, |
| | | MSGID_LDAP_CONNHANDLER_STARTED_LISTENING, handlerName); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | ErrorLogSeverity.NOTICE, |
| | | MSGID_LDAP_CONNHANDLER_STARTED_LISTENING, handlerName); |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.SEVERE_ERROR, |
| | | MSGID_LDAP_CONNHANDLER_CREATE_CHANNEL_FAILED, |
| | | configEntryDN, a.getHostAddress(), listenPort, |
| | | stackTraceToSingleLineString(e)); |
| | | ErrorLogSeverity.SEVERE_ERROR, |
| | | MSGID_LDAP_CONNHANDLER_CREATE_CHANNEL_FAILED, |
| | | currentConfig.dn(), a.getHostAddress(), listenPort, |
| | | stackTraceToSingleLineString(e)); |
| | | } |
| | | } |
| | | |
| | | |
| | | // If none of the listeners were created successfully, then consider the |
| | | // connection handler disabled and require administrative action before |
| | | // trying again. |
| | | if (numRegistered == 0) |
| | | { |
| | | // If none of the listeners were created successfully, then |
| | | // consider the connection handler disabled and require |
| | | // administrative action before trying again. |
| | | if (numRegistered == 0) { |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.FATAL_ERROR, |
| | | MSGID_LDAP_CONNHANDLER_NO_ACCEPTORS, configEntryDN); |
| | | ErrorLogSeverity.FATAL_ERROR, |
| | | MSGID_LDAP_CONNHANDLER_NO_ACCEPTORS, currentConfig.dn()); |
| | | |
| | | enabled = false; |
| | | continue; |
| | |
| | | |
| | | listening = true; |
| | | |
| | | |
| | | // Enter a loop, waiting for new connections to arrive and then |
| | | // accepting them as they come in. |
| | | // Enter a loop, waiting for new connections to arrive and |
| | | // then accepting them as they come in. |
| | | boolean lastIterationFailed = false; |
| | | while (enabled && (! shutdownRequested)) |
| | | { |
| | | try |
| | | { |
| | | if (selector.select() > 0) |
| | | { |
| | | Iterator<SelectionKey> iterator = |
| | | selector.selectedKeys().iterator(); |
| | | while (enabled && (!shutdownRequested)) { |
| | | try { |
| | | if (selector.select() > 0) { |
| | | Iterator<SelectionKey> iterator = selector |
| | | .selectedKeys().iterator(); |
| | | |
| | | while (iterator.hasNext()) |
| | | { |
| | | while (iterator.hasNext()) { |
| | | SelectionKey key = iterator.next(); |
| | | if (key.isAcceptable()) |
| | | { |
| | | if (key.isAcceptable()) { |
| | | // Accept the new client connection. |
| | | ServerSocketChannel serverChannel = |
| | | (ServerSocketChannel) key.channel(); |
| | | SocketChannel clientChannel = serverChannel.accept(); |
| | | ServerSocketChannel serverChannel = (ServerSocketChannel) key |
| | | .channel(); |
| | | SocketChannel clientChannel = serverChannel |
| | | .accept(); |
| | | LDAPClientConnection clientConnection = |
| | | new LDAPClientConnection(this, clientChannel); |
| | | InetAddress clientAddr=clientConnection.getRemoteAddress(); |
| | | // Check to see if the client is on the denied list. If so, |
| | | // then reject it immediately. |
| | | if((deniedClients != null) && (deniedClients.length > 0) && |
| | | AddressMask.maskListContains(clientAddr.getAddress(), |
| | | clientAddr.getHostName(), deniedClients)) |
| | | { |
| | | clientConnection.disconnect( |
| | | DisconnectReason.CONNECTION_REJECTED, |
| | | sendRejectionNotice, |
| | | MSGID_LDAP_CONNHANDLER_DENIED_CLIENT, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort()); |
| | | new LDAPClientConnection(this, clientChannel); |
| | | InetAddress clientAddr = clientConnection |
| | | .getRemoteAddress(); |
| | | // Check to see if the client is on the denied list. |
| | | // If so, then reject it immediately. |
| | | if ((deniedClients.length > 0) |
| | | && AddressMask.maskListContains(clientAddr |
| | | .getAddress(), clientAddr.getHostName(), |
| | | deniedClients)) { |
| | | clientConnection.disconnect( |
| | | DisconnectReason.CONNECTION_REJECTED, |
| | | currentConfig.isSendRejectionNotice(), |
| | | MSGID_LDAP_CONNHANDLER_DENIED_CLIENT, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort()); |
| | | |
| | | iterator.remove(); |
| | | continue; |
| | | iterator.remove(); |
| | | continue; |
| | | } |
| | | // Check to see if there is an allowed list and if there is |
| | | // whether the client is on that list. If not, then reject |
| | | // the connection. |
| | | if((allowedClients != null) && (allowedClients.length > 0) && |
| | | (!AddressMask.maskListContains(clientAddr.getAddress(), |
| | | clientAddr.getHostName(), allowedClients))) |
| | | { |
| | | clientConnection.disconnect( |
| | | DisconnectReason.CONNECTION_REJECTED, |
| | | sendRejectionNotice, |
| | | MSGID_LDAP_CONNHANDLER_DISALLOWED_CLIENT, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort()); |
| | | // Check to see if there is an allowed list and if |
| | | // there is whether the client is on that list. If |
| | | // not, then reject the connection. |
| | | if ((allowedClients.length > 0) |
| | | && (!AddressMask.maskListContains(clientAddr |
| | | .getAddress(), clientAddr.getHostName(), |
| | | allowedClients))) { |
| | | clientConnection.disconnect( |
| | | DisconnectReason.CONNECTION_REJECTED, |
| | | currentConfig.isSendRejectionNotice(), |
| | | MSGID_LDAP_CONNHANDLER_DISALLOWED_CLIENT, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort()); |
| | | |
| | | iterator.remove(); |
| | | continue; |
| | | iterator.remove(); |
| | | continue; |
| | | } |
| | | clientChannel.socket().setKeepAlive(useKeepAlive); |
| | | clientChannel.socket().setTcpNoDelay(useTCPNoDelay); |
| | | clientChannel.socket().setKeepAlive( |
| | | currentConfig.isUseTCPKeepAlive()); |
| | | clientChannel.socket().setTcpNoDelay( |
| | | currentConfig.isUseTCPNoDelay()); |
| | | |
| | | try |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | // Check to see if the core server rejected the connection |
| | | // (e.g., already too many connections established). |
| | | if (clientConnection.getConnectionID() < 0) |
| | | { |
| | | // Check to see if the core server rejected the |
| | | // connection (e.g., already too many connections |
| | | // established). |
| | | if (clientConnection.getConnectionID() < 0) { |
| | | // The connection will have already been closed. |
| | | iterator.remove(); |
| | | continue; |
| | | } |
| | | |
| | | // If we've gotten here, then we'll take the connection so |
| | | // invoke the post-connect plugins and register the client |
| | | // connection with a request handler. |
| | | try |
| | | { |
| | | PluginConfigManager pluginManager = |
| | | DirectoryServer.getPluginConfigManager(); |
| | | PostConnectPluginResult pluginResult = |
| | | pluginManager.invokePostConnectPlugins( |
| | | clientConnection); |
| | | if (pluginResult.connectionTerminated()) |
| | | { |
| | | // If we've gotten here, then we'll take the |
| | | // connection so invoke the post-connect plugins and |
| | | // register the client connection with a request |
| | | // handler. |
| | | try { |
| | | PluginConfigManager pluginManager = DirectoryServer |
| | | .getPluginConfigManager(); |
| | | PostConnectPluginResult pluginResult = pluginManager |
| | | .invokePostConnectPlugins(clientConnection); |
| | | if (pluginResult.connectionTerminated()) { |
| | | iterator.remove(); |
| | | continue; |
| | | } |
| | | |
| | | LDAPRequestHandler requestHandler = |
| | | requestHandlers[requestHandlerIndex++]; |
| | | if (requestHandlerIndex >= numRequestHandlers) |
| | | { |
| | | requestHandlers[requestHandlerIndex++]; |
| | | if (requestHandlerIndex >= numRequestHandlers) { |
| | | requestHandlerIndex = 0; |
| | | } |
| | | |
| | | if (requestHandler.registerClient(clientConnection)) |
| | | { |
| | | if (requestHandler |
| | | .registerClient(clientConnection)) { |
| | | logConnect(clientConnection); |
| | | } |
| | | else |
| | | { |
| | | } else { |
| | | iterator.remove(); |
| | | continue; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | int msgID = |
| | | MSGID_LDAP_CONNHANDLER_UNABLE_TO_REGISTER_CLIENT; |
| | | String message = |
| | | getMessage(msgID, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort(), |
| | | stackTraceToSingleLineString(e)); |
| | | MSGID_LDAP_CONNHANDLER_UNABLE_TO_REGISTER_CLIENT; |
| | | String message = getMessage(msgID, |
| | | clientConnection.getClientHostPort(), |
| | | clientConnection.getServerHostPort(), |
| | | stackTraceToSingleLineString(e)); |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.SEVERE_ERROR, message, msgID); |
| | | ErrorLogSeverity.SEVERE_ERROR, message, msgID); |
| | | |
| | | clientConnection.disconnect(DisconnectReason.SERVER_ERROR, |
| | | sendRejectionNotice, message, |
| | | msgID); |
| | | clientConnection.disconnect( |
| | | DisconnectReason.SERVER_ERROR, currentConfig |
| | | .isSendRejectionNotice(), message, msgID); |
| | | |
| | | iterator.remove(); |
| | | continue; |
| | |
| | | |
| | | iterator.remove(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (shutdownRequested) |
| | | { |
| | | } else { |
| | | if (shutdownRequested) { |
| | | cleanUpSelector(); |
| | | listening = false; |
| | | enabled = false; |
| | | enabled = false; |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | lastIterationFailed = false; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.SEVERE_WARNING, |
| | | MSGID_LDAP_CONNHANDLER_CANNOT_ACCEPT_CONNECTION, |
| | | configEntryDN, stackTraceToSingleLineString(e)); |
| | | ErrorLogSeverity.SEVERE_WARNING, |
| | | MSGID_LDAP_CONNHANDLER_CANNOT_ACCEPT_CONNECTION, |
| | | currentConfig.dn(), stackTraceToSingleLineString(e)); |
| | | |
| | | if (lastIterationFailed) |
| | | { |
| | | // The last time through the accept loop we also encountered a |
| | | // failure. Rather than enter a potential infinite loop of |
| | | // failures, disable this acceptor and log an error. |
| | | if (lastIterationFailed) { |
| | | // The last time through the accept loop we also |
| | | // encountered a failure. Rather than enter a potential |
| | | // infinite loop of failures, disable this acceptor and |
| | | // log an error. |
| | | int msgID = MSGID_LDAP_CONNHANDLER_CONSECUTIVE_ACCEPT_FAILURES; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | String message = getMessage(msgID, String |
| | | .valueOf(currentConfig.dn()), |
| | | stackTraceToSingleLineString(e)); |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.FATAL_ERROR, message, msgID); |
| | | ErrorLogSeverity.FATAL_ERROR, message, msgID); |
| | | |
| | | DirectoryServer.sendAlertNotification(this, |
| | | ALERT_TYPE_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, |
| | | msgID, message); |
| | | DirectoryServer |
| | | .sendAlertNotification( |
| | | this, |
| | | ALERT_TYPE_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, |
| | | msgID, message); |
| | | |
| | | enabled = false; |
| | | |
| | | try |
| | | { |
| | | try { |
| | | cleanUpSelector(); |
| | | } catch (Exception e2) { |
| | | } |
| | | catch (Exception e2) |
| | | { |
| | | } |
| | | } |
| | | else |
| | | { |
| | | } else { |
| | | lastIterationFailed = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This is very bad because we failed outside the loop. The only |
| | | // thing we can do here is log a message, send an alert, and disable the |
| | | // selector until an administrator can figure out what's going on. |
| | | // This is very bad because we failed outside the loop. The |
| | | // only thing we can do here is log a message, send an alert, |
| | | // and disable the selector until an administrator can figure |
| | | // out what's going on. |
| | | int msgID = MSGID_LDAP_CONNHANDLER_UNCAUGHT_ERROR; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | String message = getMessage(msgID, String |
| | | .valueOf(currentConfig.dn()), |
| | | stackTraceToSingleLineString(e)); |
| | | |
| | | logError(ErrorLogCategory.CONNECTION_HANDLING, |
| | | ErrorLogSeverity.SEVERE_ERROR, message, msgID); |
| | | ErrorLogSeverity.SEVERE_ERROR, message, msgID); |
| | | |
| | | DirectoryServer.sendAlertNotification(this, |
| | | ALERT_TYPE_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR, msgID, message); |
| | | ALERT_TYPE_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR, msgID, |
| | | message); |
| | | |
| | | try |
| | | { |
| | | try { |
| | | cleanUpSelector(); |
| | | } catch (Exception e2) {} |
| | | } catch (Exception e2) { |
| | | } |
| | | |
| | | enabled = false; |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * Cleans up the contents of the selector, closing any server socket channels |
| | | * that might be associated with it. Any connections that might have been |
| | | * established through those channels should not be impacted. |
| | | * Appends a string representation of this connection handler to the |
| | | * provided buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to which the information should be appended. |
| | | */ |
| | | private void cleanUpSelector() |
| | | { |
| | | try |
| | | { |
| | | Iterator<SelectionKey> iterator = selector.keys().iterator(); |
| | | while (iterator.hasNext()) |
| | | { |
| | | SelectionKey key = iterator.next(); |
| | | |
| | | try |
| | | { |
| | | key.cancel(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | |
| | | try |
| | | { |
| | | key.channel().close(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should maintain usage statistics. |
| | | * |
| | | * @return <CODE>true</CODE> if this connection handler should maintain usage |
| | | * statistics, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean keepStats() |
| | | { |
| | | return keepStats; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this connection handler should maintain usage statistics. |
| | | * |
| | | * @param keepStats Specifies whether this connection handler should |
| | | * maintain usage statistics. |
| | | */ |
| | | public void setKeepStats(boolean keepStats) |
| | | { |
| | | this.keepStats = keepStats; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of statistics maintained by this connection handler. |
| | | * |
| | | * @return The set of statistics maintained by this connection handler. |
| | | */ |
| | | public LDAPStatistics getStatTracker() |
| | | { |
| | | return statTracker; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should allow interaction with |
| | | * LDAPv2 clients. |
| | | * |
| | | * @return <CODE>true</CODE> if LDAPv2 is allowed, or <CODE>false</CODE> if |
| | | * not. |
| | | */ |
| | | public boolean allowLDAPv2() |
| | | { |
| | | return allowLDAPv2; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should allow the use of the |
| | | * StartTLS extended operation. |
| | | * |
| | | * @return <CODE>true</CODE> if StartTLS is allowed, or <CODE>false</CODE> if |
| | | * not. |
| | | */ |
| | | public boolean allowStartTLS() |
| | | { |
| | | return allowStartTLS; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this connection handler should use SSL to communicate |
| | | * with clients. |
| | | * |
| | | * @return {@code true} if this connection handler should use SSL to |
| | | * communicate with clients, or {@code false} if not. |
| | | */ |
| | | public boolean useSSL() |
| | | { |
| | | return useSSL; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the SSL client authentication policy for this connection handler. |
| | | * |
| | | * @return The SSL client authentication policy for this connection handler. |
| | | */ |
| | | public SSLClientAuthPolicy getSSLClientAuthPolicy() |
| | | { |
| | | return sslClientAuthPolicy; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of enabled SSL protocols configured for this connection |
| | | * handler. |
| | | * |
| | | * @return The set of enabled SSL protocols configured for this connection |
| | | * handler. |
| | | */ |
| | | public String[] getEnabledSSLProtocols() |
| | | { |
| | | return enabledSSLProtocols; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of enabled SSL cipher suites configured for this |
| | | * connection handler. |
| | | * |
| | | * @return The set of enabled SSL cipher suites configured for this |
| | | * connection handler. |
| | | */ |
| | | public String[] getEnabledSSLCipherSuites() |
| | | { |
| | | return enabledSSLCipherSuites; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the key manager provider that should be used for |
| | | * operations associated with this connection handler which need access to a |
| | | * key manager. |
| | | * |
| | | * @return The DN of the key manager provider that should be used for |
| | | * operations associated with this connection handler which need |
| | | * access to a key manager, or {@code null} if no key manager |
| | | * provider has been configured for this connection handler. |
| | | */ |
| | | public DN getKeyManagerProviderDN() |
| | | { |
| | | return keyManagerProviderDN; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the trust manager provider that should be used for |
| | | * operations associated with this connection handler which need access to a |
| | | * trust manager. |
| | | * |
| | | * @return The DN of the trust manager provider that should be used for |
| | | * operations associated with this connection handler which need |
| | | * access to a trust manager, or {@code null} if no trust manager |
| | | * provider has been configured for this connection handler. |
| | | */ |
| | | public DN getTrustManagerProviderDN() |
| | | { |
| | | return trustManagerProviderDN; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the nickname of the server certificate that should be used in |
| | | * conjunction with this LDAP connection handler. |
| | | * |
| | | * @return The nickname of the server certificate that should be used in |
| | | * conjunction with this LDAP connection handler. |
| | | */ |
| | | public String getSSLServerCertNickname() |
| | | { |
| | | return sslServerCertNickname; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the maximum ASN.1 element value length that will be allowed by |
| | | * this connection handler. |
| | | * |
| | | * @return The maximum ASN.1 element value length that will be allowed by |
| | | * this connection handler. |
| | | */ |
| | | public int getMaxRequestSize() |
| | | { |
| | | return maxRequestSize; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the human-readable name for this shutdown listener. |
| | | * |
| | | * @return The human-readable name for this shutdown listener. |
| | | */ |
| | | public String getShutdownListenerName() |
| | | { |
| | | return handlerName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates that the Directory Server has received a request to stop running |
| | | * and that this shutdown listener should take any action necessary to prepare |
| | | * for it. |
| | | * |
| | | * @param reason The human-readable reason for the shutdown. |
| | | */ |
| | | public void processServerShutdown(String reason) |
| | | { |
| | | shutdownRequested = true; |
| | | |
| | | try |
| | | { |
| | | for (LDAPRequestHandler requestHandler : requestHandlers) |
| | | { |
| | | try |
| | | { |
| | | requestHandler.processServerShutdown(reason); |
| | | } catch (Exception e) {} |
| | | } |
| | | } catch (Exception e) {} |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the configuration entry with which this component is |
| | | * associated. |
| | | * |
| | | * @return The DN of the configuration entry with which this component is |
| | | * associated. |
| | | */ |
| | | public DN getConfigurableComponentEntryDN() |
| | | { |
| | | return configEntryDN; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | * |
| | | * @return The set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | */ |
| | | public List<ConfigAttribute> getConfigurationAttributes() |
| | | { |
| | | LinkedList<ConfigAttribute> configAttrs = new LinkedList<ConfigAttribute>(); |
| | | |
| | | int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_ADDRESS; |
| | | ArrayList<String> listenAddressStrings = |
| | | new ArrayList<String>(listenAddresses.size()); |
| | | for (InetAddress a : listenAddresses) |
| | | { |
| | | listenAddressStrings.add(a.getHostAddress()); |
| | | } |
| | | configAttrs.add(new StringConfigAttribute(ATTR_LISTEN_ADDRESS, |
| | | getMessage(msgID), true, true, |
| | | true, listenAddressStrings)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT; |
| | | configAttrs.add(new IntegerConfigAttribute(ATTR_LISTEN_PORT, |
| | | getMessage(msgID), true, false, |
| | | true, true, 1, true, 65535, |
| | | listenPort)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_BACKLOG; |
| | | configAttrs.add(new IntegerConfigAttribute(ATTR_ACCEPT_BACKLOG, |
| | | getMessage(msgID), true, false, |
| | | true, true, 1, true, |
| | | Integer.MAX_VALUE, backlog)); |
| | | |
| | | |
| | | if (allowedClients == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOWED_CLIENTS; |
| | | ArrayList<String> allowedMasks = new ArrayList<String>(0); |
| | | configAttrs.add(new StringConfigAttribute(ATTR_ALLOWED_CLIENT, |
| | | getMessage(msgID), false, true, |
| | | false, allowedMasks)); |
| | | } |
| | | else |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOWED_CLIENTS; |
| | | ArrayList<String> allowedMasks = |
| | | new ArrayList<String>(allowedClients.length); |
| | | for (AddressMask m : allowedClients) |
| | | { |
| | | allowedMasks.add(m.toString()); |
| | | } |
| | | configAttrs.add(new StringConfigAttribute(ATTR_ALLOWED_CLIENT, |
| | | getMessage(msgID), false, true, |
| | | false, allowedMasks)); |
| | | } |
| | | |
| | | |
| | | if (deniedClients == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_DENIED_CLIENTS; |
| | | ArrayList<String> deniedMasks = new ArrayList<String>(0); |
| | | configAttrs.add(new StringConfigAttribute(ATTR_DENIED_CLIENT, |
| | | getMessage(msgID), false, true, |
| | | false, deniedMasks)); |
| | | } |
| | | else |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_DENIED_CLIENTS; |
| | | ArrayList<String> deniedMasks = |
| | | new ArrayList<String>(deniedClients.length); |
| | | for (AddressMask m : deniedClients) |
| | | { |
| | | deniedMasks.add(m.toString()); |
| | | } |
| | | configAttrs.add(new StringConfigAttribute(ATTR_DENIED_CLIENT, |
| | | getMessage(msgID), false, true, |
| | | false, deniedMasks)); |
| | | } |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_LDAPV2; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_ALLOW_LDAPV2, |
| | | getMessage(msgID), false, |
| | | allowLDAPv2)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEEP_STATS; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_KEEP_LDAP_STATS, |
| | | getMessage(msgID), false, |
| | | keepStats)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_NUM_REQUEST_HANDLERS; |
| | | configAttrs.add(new IntegerConfigAttribute(ATTR_NUM_REQUEST_HANDLERS, |
| | | getMessage(msgID), true, false, |
| | | true, true, 1, false, 0, |
| | | numRequestHandlers)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SEND_REJECTION_NOTICE; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_SEND_REJECTION_NOTICE, |
| | | getMessage(msgID), false, |
| | | sendRejectionNotice)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_KEEPALIVE; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_USE_TCP_KEEPALIVE, |
| | | getMessage(msgID), false, |
| | | useKeepAlive)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_NODELAY; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_USE_TCP_NODELAY, |
| | | getMessage(msgID), false, |
| | | useTCPNoDelay)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_REUSE_ADDRESS; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_ALLOW_REUSE_ADDRESS, |
| | | getMessage(msgID), true, |
| | | allowReuseAddress)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_MAX_REQUEST_SIZE; |
| | | configAttrs.add(new IntegerWithUnitConfigAttribute(ATTR_MAX_REQUEST_SIZE, |
| | | getMessage(msgID), false, |
| | | SIZE_UNITS, true, 0, |
| | | true, |
| | | MAX_REQUEST_SIZE_LIMIT, |
| | | maxRequestSize, |
| | | SIZE_UNIT_BYTES_FULL)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_SSL; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_USE_SSL, getMessage(msgID), |
| | | true, useSSL)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS; |
| | | configAttrs.add(new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS, |
| | | getMessage(msgID), false, |
| | | allowStartTLS)); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CLIENT_AUTH_POLICY; |
| | | HashSet<String> allowedValues = new HashSet<String>(3); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.DISABLED.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.OPTIONAL.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.REQUIRED.toString())); |
| | | configAttrs.add(new MultiChoiceConfigAttribute(ATTR_SSL_CLIENT_AUTH_POLICY, |
| | | getMessage(msgID), false, false, true, |
| | | allowedValues, sslClientAuthPolicy.toString())); |
| | | |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME; |
| | | configAttrs.add(new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME, |
| | | getMessage(msgID), false, false, |
| | | true, sslServerCertNickname)); |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_PROTOCOLS; |
| | | configAttrs.add(new StringConfigAttribute(ATTR_SSL_PROTOCOLS, |
| | | getMessage(msgID), false, true, false, |
| | | arrayToList(enabledSSLProtocols))); |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_CIPHERS; |
| | | configAttrs.add(new StringConfigAttribute(ATTR_SSL_CIPHERS, |
| | | getMessage(msgID), false, true, false, |
| | | arrayToList(enabledSSLCipherSuites))); |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN; |
| | | configAttrs.add(new DNConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID), |
| | | false, false, false, |
| | | keyManagerProviderDN)); |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN; |
| | | configAttrs.add(new DNConfigAttribute(ATTR_TRUSTMANAGER_DN, |
| | | getMessage(msgID), false, false, |
| | | false, trustManagerProviderDN)); |
| | | |
| | | |
| | | return configAttrs; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided configuration entry has an acceptable |
| | | * configuration for this component. If it does not, then detailed |
| | | * information about the problem(s) should be added to the provided list. |
| | | * |
| | | * @param configEntry The configuration entry for which to make the |
| | | * determination. |
| | | * @param unacceptableReasons A list that can be used to hold messages about |
| | | * why the provided entry does not have an |
| | | * acceptable configuration. |
| | | * |
| | | * @return <CODE>true</CODE> if the provided entry has an acceptable |
| | | * configuration for this component, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean hasAcceptableConfiguration(ConfigEntry configEntry, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | boolean configValid = true; |
| | | |
| | | |
| | | // Determine the set of addresses on which to listen. There can be |
| | | // multiple addresses specified. |
| | | int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_ADDRESS; |
| | | StringConfigAttribute addrStub = |
| | | new StringConfigAttribute(ATTR_LISTEN_ADDRESS, getMessage(msgID), |
| | | true, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute addrAttr = |
| | | (StringConfigAttribute) configEntry.getConfigAttribute(addrStub); |
| | | if ((addrAttr == null) || addrAttr.activeValues().isEmpty()) |
| | | { |
| | | // This is fine -- we'll just listen on all IPv4 addresses. |
| | | } |
| | | else |
| | | { |
| | | for (String s : addrAttr.activeValues()) |
| | | { |
| | | try |
| | | { |
| | | InetAddress.getByName(s); |
| | | } |
| | | catch (UnknownHostException uhe) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, uhe); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_UNKNOWN_LISTEN_ADDRESS; |
| | | unacceptableReasons.add(getMessage(msgID, s, |
| | | stackTraceToSingleLineString(uhe))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_LISTEN_ADDRESS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the port on which to listen. There may only be a single port |
| | | // specified. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT; |
| | | IntegerConfigAttribute portStub = |
| | | new IntegerConfigAttribute(ATTR_LISTEN_PORT, getMessage(msgID), true, |
| | | false, false, true, 1, true, 65535); |
| | | try |
| | | { |
| | | IntegerConfigAttribute portAttr = |
| | | (IntegerConfigAttribute) configEntry.getConfigAttribute(portStub); |
| | | if (portAttr == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_NO_LISTEN_PORT; |
| | | unacceptableReasons.add(getMessage(msgID, |
| | | String.valueOf(configEntryDN))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_LISTEN_PORT; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the accept backlog to use. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_BACKLOG; |
| | | IntegerConfigAttribute backlogStub = |
| | | new IntegerConfigAttribute(ATTR_ACCEPT_BACKLOG, getMessage(msgID), |
| | | true, false, true, true, 1, true, |
| | | Integer.MAX_VALUE); |
| | | try |
| | | { |
| | | IntegerConfigAttribute backlogAttr = |
| | | (IntegerConfigAttribute) configEntry.getConfigAttribute(backlogStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_BACKLOG; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the set of allowed clients. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOWED_CLIENTS; |
| | | StringConfigAttribute allowedStub = |
| | | new StringConfigAttribute(ATTR_ALLOWED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute allowedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(allowedStub); |
| | | if (allowedAttr != null) |
| | | { |
| | | for (String s : allowedAttr.activeValues()) |
| | | { |
| | | try |
| | | { |
| | | AddressMask.decode(s); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | unacceptableReasons.add(getMessage(msgID, s, ATTR_ALLOWED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOWED_CLIENTS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the set of denied clients. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_DENIED_CLIENTS; |
| | | StringConfigAttribute deniedStub = |
| | | new StringConfigAttribute(ATTR_DENIED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute deniedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(deniedStub); |
| | | if (deniedAttr != null) |
| | | { |
| | | for (String s : deniedAttr.activeValues()) |
| | | { |
| | | try |
| | | { |
| | | AddressMask.decode(s); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | unacceptableReasons.add(getMessage(msgID, s, ATTR_DENIED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_DENIED_CLIENTS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow LDAPv2 clients. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_LDAPV2; |
| | | BooleanConfigAttribute allowLDAPv2Stub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_LDAPV2, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute allowLDAPv2Attr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(allowLDAPv2Stub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_LDAPV2; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to keep LDAP statistics. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEEP_STATS; |
| | | BooleanConfigAttribute keepStatsStub = |
| | | new BooleanConfigAttribute(ATTR_KEEP_LDAP_STATS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepStatsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepStatsStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEEP_STATS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the number of request handlers to maintain. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_NUM_REQUEST_HANDLERS; |
| | | IntegerConfigAttribute reqHandlerStub = |
| | | new IntegerConfigAttribute(ATTR_NUM_REQUEST_HANDLERS, |
| | | getMessage(msgID), true, false, true, |
| | | true, 1, false, 0); |
| | | try |
| | | { |
| | | IntegerConfigAttribute reqHandlerAttr = |
| | | (IntegerConfigAttribute) |
| | | configEntry.getConfigAttribute(reqHandlerStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_NUM_REQUEST_HANDLERS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to send a notice to clients on rejection. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SEND_REJECTION_NOTICE; |
| | | BooleanConfigAttribute notifyRejectsStub = |
| | | new BooleanConfigAttribute(ATTR_SEND_REJECTION_NOTICE, |
| | | getMessage(msgID), false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute notifyRejectsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(notifyRejectsStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SEND_REJECTION_NOTICE; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP keepalive. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_KEEPALIVE; |
| | | BooleanConfigAttribute keepAliveStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_KEEPALIVE, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepAliveAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepAliveStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_KEEPALIVE; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP nodelay. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_NODELAY; |
| | | BooleanConfigAttribute noDelayStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_NODELAY, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute noDelayAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(noDelayStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_NODELAY; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow reuse of address/port combinations. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_REUSE_ADDRESS; |
| | | BooleanConfigAttribute reuseAddrStub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_REUSE_ADDRESS, |
| | | getMessage(msgID), true); |
| | | try |
| | | { |
| | | BooleanConfigAttribute reuseAddrAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(reuseAddrStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_REUSE_ADDRESS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the maximum allowed request size. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_MAX_REQUEST_SIZE; |
| | | IntegerWithUnitConfigAttribute maxReqSizeStub = |
| | | new IntegerWithUnitConfigAttribute(ATTR_MAX_REQUEST_SIZE, |
| | | getMessage(msgID), false, |
| | | SIZE_UNITS, true, 0, true, |
| | | MAX_REQUEST_SIZE_LIMIT); |
| | | try |
| | | { |
| | | IntegerWithUnitConfigAttribute maxReqSizeAttr = |
| | | (IntegerWithUnitConfigAttribute) |
| | | configEntry.getConfigAttribute(maxReqSizeStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_MAX_REQUEST_SIZE; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine whether to use SSL. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_SSL; |
| | | boolean tmpUseSSL; |
| | | BooleanConfigAttribute useSSLStub = |
| | | new BooleanConfigAttribute(ATTR_USE_SSL, getMessage(msgID), true); |
| | | try |
| | | { |
| | | BooleanConfigAttribute useSSLAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(useSSLStub); |
| | | if (useSSLAttr == null) |
| | | { |
| | | tmpUseSSL = DEFAULT_USE_SSL; |
| | | } |
| | | else |
| | | { |
| | | tmpUseSSL = useSSLAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_SSL; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | tmpUseSSL = DEFAULT_USE_SSL; |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow the StartTLS extended operation. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS; |
| | | BooleanConfigAttribute startTLSStub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute startTLSAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(startTLSStub); |
| | | boolean tmpAllowStartTLS; |
| | | if (startTLSAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | tmpAllowStartTLS = DEFAULT_ALLOW_STARTTLS; |
| | | } |
| | | else |
| | | { |
| | | tmpAllowStartTLS = startTLSAttr.activeValue(); |
| | | } |
| | | |
| | | |
| | | // See if both SSL and startTLS are configured. If so, we'll have to |
| | | // disable startTLS because they can't both be used concurrently. |
| | | if (tmpUseSSL && tmpAllowStartTLS) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_HAVE_SSL_AND_STARTTLS; |
| | | unacceptableReasons.add(getMessage(msgID, |
| | | String.valueOf(configEntryDN))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_STARTTLS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine how to handle SSL client authentication. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CLIENT_AUTH_POLICY; |
| | | HashSet<String> allowedValues = new HashSet<String>(3); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.DISABLED.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.OPTIONAL.toString())); |
| | | allowedValues.add(toLowerCase(SSLClientAuthPolicy.REQUIRED.toString())); |
| | | MultiChoiceConfigAttribute sslAuthPolicyStub = |
| | | new MultiChoiceConfigAttribute(ATTR_SSL_CLIENT_AUTH_POLICY, |
| | | getMessage(msgID), false, false, true, |
| | | allowedValues); |
| | | try |
| | | { |
| | | MultiChoiceConfigAttribute sslAuthPolicyAttr = |
| | | (MultiChoiceConfigAttribute) |
| | | configEntry.getConfigAttribute(sslAuthPolicyStub); |
| | | if (sslAuthPolicyAttr == null) |
| | | { |
| | | // This is fine -- We'll just use the default. |
| | | } |
| | | else |
| | | { |
| | | SSLClientAuthPolicy tmpPolicy = SSLClientAuthPolicy.policyForName( |
| | | sslAuthPolicyAttr.activeValue()); |
| | | if (tmpPolicy == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_SSL_CLIENT_AUTH_POLICY; |
| | | unacceptableReasons.add(getMessage(msgID, |
| | | sslAuthPolicyAttr.activeValue(), |
| | | String.valueOf(configEntryDN))); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CLIENT_AUTH_POLICY; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine which SSL certificate to use. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME; |
| | | StringConfigAttribute certNameStub = |
| | | new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME, getMessage(msgID), |
| | | false, false, true); |
| | | try |
| | | { |
| | | StringConfigAttribute certNameAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(certNameStub); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CERT_NICKNAME; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the set of SSL protocols to allow. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_PROTOCOLS; |
| | | StringConfigAttribute sslProtocolsStub = |
| | | new StringConfigAttribute(ATTR_SSL_PROTOCOLS, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslProtocolsAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslProtocolsStub); |
| | | // FIXME -- Is there a good way to determine the set of supported |
| | | // protocols to validate what the user has provided? |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_PROTOCOLS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the set of SSL cipher suites to allow. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_CIPHERS; |
| | | StringConfigAttribute sslCiphersStub = |
| | | new StringConfigAttribute(ATTR_SSL_CIPHERS, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslCiphersAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslCiphersStub); |
| | | // FIXME -- Is there a good way to determine the set of supported cipher |
| | | // suites to validate what the user has provided? |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CIPHERS; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the key manager provider to use. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN; |
| | | DNConfigAttribute keyManagerStub = |
| | | new DNConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute keyManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(keyManagerStub); |
| | | if (keyManagerAttr != null) |
| | | { |
| | | DN keyManagerProviderDN = keyManagerAttr.activeValue(); |
| | | KeyManagerProvider provider = |
| | | DirectoryServer.getKeyManagerProvider(keyManagerProviderDN); |
| | | if (provider == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_KEYMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(keyManagerProviderDN)); |
| | | unacceptableReasons.add(message); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEYMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | unacceptableReasons.add(message); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | // Determine the trust manager provider to use. |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN; |
| | | DNConfigAttribute trustManagerStub = |
| | | new DNConfigAttribute(ATTR_TRUSTMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute trustManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(trustManagerStub); |
| | | if (trustManagerAttr != null) |
| | | { |
| | | DN trustManagerProviderDN = trustManagerAttr.activeValue(); |
| | | TrustManagerProvider provider = |
| | | DirectoryServer.getTrustManagerProvider(trustManagerProviderDN); |
| | | if (provider == null) |
| | | { |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_TRUSTMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(trustManagerProviderDN)); |
| | | unacceptableReasons.add(message); |
| | | configValid = false; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_TRUSTMANAGER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | unacceptableReasons.add(message); |
| | | configValid = false; |
| | | } |
| | | |
| | | |
| | | return configValid; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Makes a best-effort attempt to apply the configuration contained in the |
| | | * provided entry. Information about the result of this processing should be |
| | | * added to the provided message list. Information should always be added to |
| | | * this list if a configuration change could not be applied. If detailed |
| | | * results are requested, then information about the changes applied |
| | | * successfully (and optionally about parameters that were not changed) should |
| | | * also be included. |
| | | * |
| | | * @param configEntry The entry containing the new configuration to |
| | | * apply for this component. |
| | | * @param detailedResults Indicates whether detailed information about the |
| | | * processing should be added to the list. |
| | | * |
| | | * @return Information about the result of the configuration update. |
| | | */ |
| | | public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry, |
| | | boolean detailedResults) |
| | | { |
| | | // Create variables to include in the response. |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | |
| | | // The set of addresses and the port on which to listen are not dynamically |
| | | // reconfigurable, so we can skip them. |
| | | |
| | | |
| | | // The backlog is not dynamically reconfigurable, so we can skip it. |
| | | |
| | | |
| | | // Determine the set of allowed clients. |
| | | HashSet<AddressMask> newAllowedClients = null; |
| | | int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOWED_CLIENTS; |
| | | StringConfigAttribute allowedStub = |
| | | new StringConfigAttribute(ATTR_ALLOWED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute allowedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(allowedStub); |
| | | if (allowedAttr != null) |
| | | { |
| | | newAllowedClients = new HashSet<AddressMask>(); |
| | | |
| | | for (String s : allowedAttr.pendingValues()) |
| | | { |
| | | try |
| | | { |
| | | newAllowedClients.add(AddressMask.decode(s)); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | messages.add(getMessage(msgID, s, ATTR_ALLOWED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOWED_CLIENTS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | } |
| | | |
| | | boolean allowedClientsChanged = false; |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | if ((allowedClients == null) || (allowedClients.length == 0)) |
| | | { |
| | | allowedClientsChanged = (! ((newAllowedClients == null) || |
| | | newAllowedClients.isEmpty())); |
| | | } |
| | | else if ((newAllowedClients == null) || newAllowedClients.isEmpty()) |
| | | { |
| | | allowedClientsChanged = true; |
| | | } |
| | | else if (allowedClients.length != newAllowedClients.size()) |
| | | { |
| | | allowedClientsChanged = true; |
| | | } |
| | | else |
| | | { |
| | | for (AddressMask m : allowedClients) |
| | | { |
| | | if (! newAllowedClients.contains(m)) |
| | | { |
| | | allowedClientsChanged = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // Determine the set of denied clients. |
| | | HashSet<AddressMask> newDeniedClients = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_DENIED_CLIENTS; |
| | | StringConfigAttribute deniedStub = |
| | | new StringConfigAttribute(ATTR_DENIED_CLIENT, getMessage(msgID), |
| | | false, true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute deniedAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(deniedStub); |
| | | if (deniedAttr != null) |
| | | { |
| | | newDeniedClients = new HashSet<AddressMask>(); |
| | | |
| | | for (String s : deniedAttr.pendingValues()) |
| | | { |
| | | try |
| | | { |
| | | newDeniedClients.add(AddressMask.decode(s)); |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, ce); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_ADDRESS_MASK; |
| | | messages.add(getMessage(msgID, s, ATTR_DENIED_CLIENT, |
| | | String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(ce))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_DENIED_CLIENTS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | } |
| | | |
| | | boolean deniedClientsChanged = false; |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | if ((deniedClients == null) || (deniedClients.length == 0)) |
| | | { |
| | | deniedClientsChanged = (! ((newDeniedClients == null) || |
| | | newDeniedClients.isEmpty())); |
| | | } |
| | | else if ((newDeniedClients == null) || newDeniedClients.isEmpty()) |
| | | { |
| | | deniedClientsChanged = true; |
| | | } |
| | | else if (deniedClients.length != newDeniedClients.size()) |
| | | { |
| | | deniedClientsChanged = true; |
| | | } |
| | | else |
| | | { |
| | | for (AddressMask m : deniedClients) |
| | | { |
| | | if (! newDeniedClients.contains(m)) |
| | | { |
| | | deniedClientsChanged = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // Determine whether to allow LDAPv2 clients. |
| | | boolean newAllowLDAPv2; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_LDAPV2; |
| | | BooleanConfigAttribute allowLDAPv2Stub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_LDAPV2, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute allowLDAPv2Attr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(allowLDAPv2Stub); |
| | | if (allowLDAPv2Attr == null) |
| | | { |
| | | newAllowLDAPv2 = DEFAULT_ALLOW_LDAPV2; |
| | | } |
| | | else |
| | | { |
| | | newAllowLDAPv2 = allowLDAPv2Attr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_LDAPV2; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newAllowLDAPv2 = DEFAULT_ALLOW_LDAPV2; |
| | | } |
| | | |
| | | |
| | | // Determine whether to keep LDAP statistics. |
| | | boolean newKeepStats; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEEP_STATS; |
| | | BooleanConfigAttribute keepStatsStub = |
| | | new BooleanConfigAttribute(ATTR_KEEP_LDAP_STATS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepStatsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepStatsStub); |
| | | if (keepStatsAttr == null) |
| | | { |
| | | newKeepStats = DEFAULT_KEEP_LDAP_STATS; |
| | | } |
| | | else |
| | | { |
| | | newKeepStats = keepStatsAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEEP_STATS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newKeepStats = DEFAULT_KEEP_LDAP_STATS; |
| | | } |
| | | |
| | | |
| | | // The number of request handlers to maintain is not dynamically |
| | | // reconfigurable, so we can skip it. |
| | | |
| | | |
| | | // Determine whether to send a notice to clients on rejection. |
| | | boolean newSendRejectionNotice; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SEND_REJECTION_NOTICE; |
| | | BooleanConfigAttribute notifyRejectsStub = |
| | | new BooleanConfigAttribute(ATTR_SEND_REJECTION_NOTICE, |
| | | getMessage(msgID), false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute notifyRejectsAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(notifyRejectsStub); |
| | | if (notifyRejectsAttr == null) |
| | | { |
| | | newSendRejectionNotice = DEFAULT_SEND_REJECTION_NOTICE; |
| | | } |
| | | else |
| | | { |
| | | newSendRejectionNotice = notifyRejectsAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SEND_REJECTION_NOTICE; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newSendRejectionNotice = DEFAULT_SEND_REJECTION_NOTICE; |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP keepalive. |
| | | boolean newUseKeepAlive; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_KEEPALIVE; |
| | | BooleanConfigAttribute keepAliveStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_KEEPALIVE, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute keepAliveAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(keepAliveStub); |
| | | if (keepAliveAttr == null) |
| | | { |
| | | newUseKeepAlive = DEFAULT_USE_TCP_KEEPALIVE; |
| | | } |
| | | else |
| | | { |
| | | newUseKeepAlive = keepAliveAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_KEEPALIVE; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newUseKeepAlive = DEFAULT_USE_TCP_KEEPALIVE; |
| | | } |
| | | |
| | | |
| | | // Determine whether to use TCP nodelay. |
| | | boolean newUseTCPNoDelay; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_TCP_NODELAY; |
| | | BooleanConfigAttribute noDelayStub = |
| | | new BooleanConfigAttribute(ATTR_USE_TCP_NODELAY, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute noDelayAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(noDelayStub); |
| | | if (noDelayAttr == null) |
| | | { |
| | | newUseTCPNoDelay = DEFAULT_USE_TCP_NODELAY; |
| | | } |
| | | else |
| | | { |
| | | newUseTCPNoDelay = noDelayAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_USE_TCP_NODELAY; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newUseTCPNoDelay = DEFAULT_USE_TCP_NODELAY; |
| | | } |
| | | |
| | | |
| | | // The reuse address option isn't dynamically reconfigurable, so we can skip |
| | | // it. |
| | | |
| | | |
| | | // Determine the maximum allowed request size. |
| | | int newMaxRequestSize; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_MAX_REQUEST_SIZE; |
| | | IntegerWithUnitConfigAttribute maxReqSizeStub = |
| | | new IntegerWithUnitConfigAttribute(ATTR_MAX_REQUEST_SIZE, |
| | | getMessage(msgID), false, |
| | | SIZE_UNITS, true, 0, true, |
| | | MAX_REQUEST_SIZE_LIMIT); |
| | | try |
| | | { |
| | | IntegerWithUnitConfigAttribute maxReqSizeAttr = |
| | | (IntegerWithUnitConfigAttribute) |
| | | configEntry.getConfigAttribute(maxReqSizeStub); |
| | | if (maxReqSizeAttr == null) |
| | | { |
| | | newMaxRequestSize = DEFAULT_MAX_REQUEST_SIZE; |
| | | } |
| | | else |
| | | { |
| | | newMaxRequestSize = (int) maxReqSizeAttr.pendingCalculatedValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_MAX_REQUEST_SIZE; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newMaxRequestSize = DEFAULT_MAX_REQUEST_SIZE; |
| | | } |
| | | |
| | | |
| | | // The flag specifying whether to use SSL is not dynamically reconfigurable, |
| | | // so we can skip it. |
| | | |
| | | |
| | | // Determine whether to allow the StartTLS extended operation. |
| | | boolean newAllowStartTLS; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS; |
| | | BooleanConfigAttribute startTLSStub = |
| | | new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS, getMessage(msgID), |
| | | false); |
| | | try |
| | | { |
| | | BooleanConfigAttribute startTLSAttr = |
| | | (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(startTLSStub); |
| | | if (startTLSAttr == null) |
| | | { |
| | | // This is fine -- we'll just use the default. |
| | | newAllowStartTLS = DEFAULT_ALLOW_STARTTLS; |
| | | } |
| | | else |
| | | { |
| | | newAllowStartTLS = startTLSAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_ALLOW_STARTTLS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newAllowStartTLS = DEFAULT_ALLOW_STARTTLS; |
| | | } |
| | | |
| | | |
| | | // The SSL client authentication policy and SSL certificate nickname are not |
| | | // dynamically reconfigurable, so we can skip them. |
| | | |
| | | |
| | | // Determine the set of SSL protocols to allow. |
| | | String[] newSSLProtocols; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_PROTOCOLS; |
| | | StringConfigAttribute sslProtocolsStub = |
| | | new StringConfigAttribute(ATTR_SSL_PROTOCOLS, getMessage(msgID), false, |
| | | true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslProtocolsAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslProtocolsStub); |
| | | if (sslProtocolsAttr == null) |
| | | { |
| | | newSSLProtocols = null; |
| | | } |
| | | else |
| | | { |
| | | // FIXME -- Is there a good way to validate the provided set of values? |
| | | newSSLProtocols = listToArray(sslProtocolsAttr.pendingValues()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_PROTOCOLS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newSSLProtocols = null; |
| | | } |
| | | |
| | | |
| | | |
| | | // Determine the set of SSL cipher suites to allow. |
| | | String[] newSSLCiphers; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_ENABLED_CIPHERS; |
| | | StringConfigAttribute sslCiphersStub = |
| | | new StringConfigAttribute(ATTR_SSL_CIPHERS, getMessage(msgID), false, |
| | | true, false); |
| | | try |
| | | { |
| | | StringConfigAttribute sslCiphersAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(sslCiphersStub); |
| | | if (sslCiphersAttr == null) |
| | | { |
| | | newSSLCiphers = null; |
| | | } |
| | | else |
| | | { |
| | | // FIXME -- Is there a good way to validate the provided set of values? |
| | | newSSLCiphers = listToArray(sslCiphersAttr.pendingValues()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_SSL_CIPHERS; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | newSSLCiphers = null; |
| | | } |
| | | |
| | | |
| | | // Determine the key manager provider to use. |
| | | DN newKeyManagerDN = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN; |
| | | DNConfigAttribute keyManagerStub = |
| | | new DNConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute keyManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(keyManagerStub); |
| | | if (keyManagerAttr != null) |
| | | { |
| | | newKeyManagerDN = keyManagerAttr.activeValue(); |
| | | KeyManagerProvider provider = |
| | | DirectoryServer.getKeyManagerProvider(newKeyManagerDN); |
| | | if (provider == null) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.CONSTRAINT_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_KEYMANAGER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(newKeyManagerDN))); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.CONSTRAINT_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_KEYMANAGER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | } |
| | | |
| | | |
| | | // Determine the trust manager provider to use. |
| | | DN newTrustManagerDN = null; |
| | | msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN; |
| | | DNConfigAttribute trustManagerStub = |
| | | new DNConfigAttribute(ATTR_TRUSTMANAGER_DN, getMessage(msgID), false, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute trustManagerAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(trustManagerStub); |
| | | if (trustManagerAttr != null) |
| | | { |
| | | newTrustManagerDN = trustManagerAttr.activeValue(); |
| | | TrustManagerProvider provider = |
| | | DirectoryServer.getTrustManagerProvider(newTrustManagerDN); |
| | | if (provider == null) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.CONSTRAINT_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_INVALID_TRUSTMANAGER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(newTrustManagerDN))); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.CONSTRAINT_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_LDAP_CONNHANDLER_CANNOT_DETERMINE_TRUSTMANAGER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | } |
| | | |
| | | |
| | | // If the provided configuration is acceptable, then apply it. |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | if (allowedClientsChanged) |
| | | { |
| | | AddressMask[] newAllowedArray; |
| | | if ((newAllowedClients == null) || newAllowedClients.isEmpty()) |
| | | { |
| | | newAllowedArray = null; |
| | | } |
| | | else |
| | | { |
| | | newAllowedArray = new AddressMask[newAllowedClients.size()]; |
| | | newAllowedClients.toArray(newAllowedArray); |
| | | } |
| | | |
| | | allowedClients = newAllowedArray; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_ALLOWED_CLIENTS, |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (deniedClientsChanged) |
| | | { |
| | | AddressMask[] newDeniedArray; |
| | | if ((newDeniedClients == null) || newDeniedClients.isEmpty()) |
| | | { |
| | | newDeniedArray = null; |
| | | } |
| | | else |
| | | { |
| | | newDeniedArray = new AddressMask[newDeniedClients.size()]; |
| | | newDeniedClients.toArray(newDeniedArray); |
| | | } |
| | | |
| | | deniedClients = newDeniedArray; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_DENIED_CLIENTS, |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (allowLDAPv2 != newAllowLDAPv2) |
| | | { |
| | | allowLDAPv2 = newAllowLDAPv2; |
| | | if (allowLDAPv2) |
| | | { |
| | | if (statTracker == null) |
| | | { |
| | | statTracker = new LDAPStatistics(handlerName + " Statistics"); |
| | | } |
| | | else |
| | | { |
| | | statTracker.clearStatistics(); |
| | | } |
| | | } |
| | | |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_ALLOW_LDAPV2, |
| | | String.valueOf(newAllowLDAPv2), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (keepStats != newKeepStats) |
| | | { |
| | | keepStats = newKeepStats; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_KEEP_STATS, |
| | | String.valueOf(newKeepStats), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (sendRejectionNotice != newSendRejectionNotice) |
| | | { |
| | | sendRejectionNotice = newSendRejectionNotice; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage( |
| | | MSGID_LDAP_CONNHANDLER_NEW_SEND_REJECTION_NOTICE, |
| | | String.valueOf(newSendRejectionNotice), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (useKeepAlive != newUseKeepAlive) |
| | | { |
| | | useKeepAlive = newUseKeepAlive; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_USE_KEEPALIVE, |
| | | String.valueOf(newUseKeepAlive), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (useTCPNoDelay != newUseTCPNoDelay) |
| | | { |
| | | useTCPNoDelay = newUseTCPNoDelay; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_USE_TCP_NODELAY, |
| | | String.valueOf(newUseTCPNoDelay), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (maxRequestSize != newMaxRequestSize) |
| | | { |
| | | maxRequestSize = newMaxRequestSize; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_MAX_REQUEST_SIZE, |
| | | String.valueOf(newMaxRequestSize), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | if (allowStartTLS != newAllowStartTLS) |
| | | { |
| | | allowStartTLS = newAllowStartTLS; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_ALLOW_STARTTLS, |
| | | String.valueOf(newAllowStartTLS), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Update enabled SSL protocols. |
| | | if (! Arrays.equals(enabledSSLProtocols, newSSLProtocols)) |
| | | { |
| | | enabledSSLProtocols = newSSLProtocols; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_SSL_PROTOCOLS, |
| | | Arrays.toString(newSSLProtocols), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Update enabled SSL cipher suites. |
| | | if (! Arrays.equals(enabledSSLCipherSuites, newSSLCiphers)) |
| | | { |
| | | enabledSSLCipherSuites = newSSLCiphers; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_SSL_CIPHERS, |
| | | Arrays.toString(newSSLCiphers), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Update the key manager provider DN. |
| | | if (keyManagerProviderDN == null) |
| | | { |
| | | if (newKeyManagerDN != null) |
| | | { |
| | | keyManagerProviderDN = newKeyManagerDN; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_KEYMANAGER_DN, |
| | | String.valueOf(newKeyManagerDN), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | } |
| | | else if ((newKeyManagerDN == null) || |
| | | (! keyManagerProviderDN.equals(newKeyManagerDN))) |
| | | { |
| | | keyManagerProviderDN = newKeyManagerDN; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_KEYMANAGER_DN, |
| | | String.valueOf(newKeyManagerDN), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Update the trust manager provider DN. |
| | | if (trustManagerProviderDN == null) |
| | | { |
| | | if (newTrustManagerDN != null) |
| | | { |
| | | trustManagerProviderDN = newTrustManagerDN; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_TRUSTMANAGER_DN, |
| | | String.valueOf(newTrustManagerDN), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | } |
| | | else if ((newTrustManagerDN == null) || |
| | | (! trustManagerProviderDN.equals(newTrustManagerDN))) |
| | | { |
| | | trustManagerProviderDN = newTrustManagerDN; |
| | | if (detailedResults) |
| | | { |
| | | messages.add(getMessage(MSGID_LDAP_CONNHANDLER_NEW_TRUSTMANAGER_DN, |
| | | String.valueOf(newTrustManagerDN), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Appends a string representation of this connection handler to the provided |
| | | * buffer. |
| | | * |
| | | * @param buffer The buffer to which the information should be appended. |
| | | */ |
| | | public void toString(StringBuilder buffer) |
| | | { |
| | | public void toString(StringBuilder buffer) { |
| | | buffer.append(handlerName); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the configuration entry with which this alert generator |
| | | * is associated. |
| | | * Indicates whether this connection handler should use SSL to |
| | | * communicate with clients. |
| | | * |
| | | * @return The DN of the configuration entry with which this alert generator |
| | | * is associated. |
| | | * @return {@code true} if this connection handler should use SSL to |
| | | * communicate with clients, or {@code false} if not. |
| | | */ |
| | | public DN getComponentEntryDN() |
| | | { |
| | | return configEntryDN; |
| | | public boolean useSSL() { |
| | | return currentConfig.isUseSSL(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the fully-qualified name of the Java class for this alert |
| | | * generator implementation. |
| | | * |
| | | * @return The fully-qualified name of the Java class for this alert |
| | | * generator implementation. |
| | | * Cleans up the contents of the selector, closing any server socket |
| | | * channels that might be associated with it. Any connections that |
| | | * might have been established through those channels should not be |
| | | * impacted. |
| | | */ |
| | | public String getClassName() |
| | | { |
| | | return CLASS_NAME; |
| | | } |
| | | private void cleanUpSelector() { |
| | | try { |
| | | Iterator<SelectionKey> iterator = selector.keys().iterator(); |
| | | while (iterator.hasNext()) { |
| | | SelectionKey key = iterator.next(); |
| | | |
| | | try { |
| | | key.cancel(); |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Retrieves information about the set of alerts that this generator may |
| | | * produce. The map returned should be between the notification type for a |
| | | * particular notification and the human-readable description for that |
| | | * notification. This alert generator must not generate any alerts with types |
| | | * that are not contained in this list. |
| | | * |
| | | * @return Information about the set of alerts that this generator may |
| | | * produce. |
| | | */ |
| | | public LinkedHashMap<String,String> getAlerts() |
| | | { |
| | | LinkedHashMap<String,String> alerts = new LinkedHashMap<String,String>(); |
| | | |
| | | alerts.put(ALERT_TYPE_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, |
| | | ALERT_DESCRIPTION_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES); |
| | | alerts.put(ALERT_TYPE_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR, |
| | | ALERT_DESCRIPTION_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR); |
| | | |
| | | return alerts; |
| | | try { |
| | | key.channel().close(); |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |