From 22094368c2865dcfb6daf8366425212b721a4657 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 05 Feb 2009 17:42:14 +0000
Subject: [PATCH] Merge ASN1 branch to trunk
---
opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java | 248 +++++++++++++++++++++----------------------------
1 files changed, 107 insertions(+), 141 deletions(-)
diff --git a/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java b/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
index 8b5da30..7499f45 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.protocols.ldap;
import org.opends.messages.Message;
@@ -45,6 +45,8 @@
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -53,26 +55,31 @@
import java.util.List;
import java.util.Set;
+import javax.net.ssl.SSLContext;
+
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.ConnectionHandlerCfg;
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.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.PluginResult;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.core.QueueingStrategy;
import org.opends.server.core.WorkQueueStrategy;
-import org.opends.server.extensions.NullConnectionSecurityProvider;
-import org.opends.server.extensions.TLSConnectionSecurityProvider;
+import org.opends.server.extensions.NullKeyManagerProvider;
+import org.opends.server.extensions.NullTrustManagerProvider;
+import org.opends.server.extensions.TLSByteChannel;
import org.opends.server.types.AddressMask;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.DirectoryException;
import org.opends.server.types.DisconnectReason;
@@ -80,6 +87,7 @@
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SSLClientAuthPolicy;
+import org.opends.server.util.SelectableCertificateKeyManager;
import org.opends.server.util.StaticUtils;
@@ -188,10 +196,6 @@
// 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;
-
// Queueing strategy
private final QueueingStrategy queueingStrategy;
@@ -203,6 +207,13 @@
// The friendly name of this connection handler.
private String friendlyName;
+ //SSL instance name used in context creation.
+ private static final String SSL_CONTEXT_INSTANCE_NAME = "TLS";
+
+ //SSL context.
+ private SSLContext sslContext;
+ private boolean sslConfig = false;
+
/**
* Creates a new instance of this LDAP connection handler. It must
* be initialized before it may be used.
@@ -308,20 +319,10 @@
new AddressMask[0]);
deniedClients = config.getDeniedClient().toArray(
new AddressMask[0]);
+ //Reconfigure SSL context if needed.
+ if (config.isUseSSL() || config.isAllowStartTLS()) {
+ sslConfig = true;
- // Get the supported SSL ciphers and protocols.
- Set<String> ciphers = config.getSSLCipherSuite();
- if (ciphers.isEmpty()) {
- enabledSSLCipherSuites = null;
- } else {
- enabledSSLCipherSuites = ciphers.toArray(new String[0]);
- }
-
- Set<String> protocols = config.getSSLProtocol();
- if (protocols.isEmpty()) {
- enabledSSLProtocols = null;
- } else {
- enabledSSLProtocols = protocols.toArray(new String[0]);
}
if (config.isAllowLDAPV2())
@@ -491,21 +492,6 @@
- /**
- * 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();
- }
-
/**
@@ -575,16 +561,6 @@
- /**
- * 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();
- }
@@ -614,22 +590,6 @@
- /**
- * 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}
@@ -651,51 +611,7 @@
throw new InitializationException(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.getSSLCipherSuite();
- if (ciphers.isEmpty()) {
- enabledSSLCipherSuites = null;
- } else {
- enabledSSLCipherSuites = ciphers.toArray(new String[0]);
- }
-
- Set<String> protocols = config.getSSLProtocol();
- 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);
- }
+ protocol = "LDAP";
// Save this configuration for future reference.
currentConfig = config;
@@ -705,6 +621,9 @@
new AddressMask[0]);
deniedClients = config.getDeniedClient().toArray(
new AddressMask[0]);
+ //Setup SSL context if needed.
+ if (config.isUseSSL() || config.isAllowStartTLS())
+ sslConfig=true;
// Save properties that cannot be dynamically modified.
allowReuseAddress = config.isAllowTCPReuseAddress();
@@ -728,13 +647,6 @@
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(this, handlerName + " Statistics");
@@ -819,7 +731,6 @@
}
}
}
-
return isConfigurationChangeAcceptable(config, unacceptableReasons);
}
@@ -992,9 +903,8 @@
.channel();
SocketChannel clientChannel = serverChannel
.accept();
- LDAPClientConnection clientConnection =
- new LDAPClientConnection(this, clientChannel);
-
+ LDAPClientConnection clientConnection =
+ createClientConnection(clientChannel);
// Check to see if the core server rejected the
// connection (e.g., already too many connections
// established).
@@ -1043,29 +953,6 @@
clientChannel.socket().setTcpNoDelay(
currentConfig.isUseTCPNoDelay());
- try
- {
- ConnectionSecurityProvider connectionSecurityProvider =
- securityProvider.newInstance(clientConnection,
- clientChannel);
- clientConnection.setConnectionSecurityProvider(
- connectionSecurityProvider);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- clientConnection.disconnect(
- DisconnectReason.SECURITY_PROBLEM, false,
- ERR_LDAP_CONNHANDLER_CANNOT_SET_SECURITY_PROVIDER.get(
- String.valueOf(e)));
- 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
@@ -1276,4 +1163,83 @@
return queueingStrategy;
}
+ private LDAPClientConnection
+ createClientConnection(SocketChannel socketChannel)
+ throws DirectoryException {
+ if(sslConfig) {
+ configSSL(currentConfig);
+ sslConfig=false;
+ }
+ LDAPClientConnection c =
+ new LDAPClientConnection(this, socketChannel);
+ if(currentConfig.isUseSSL()) {
+ TLSByteChannel tlsByteChannel = getTLSByteChannel(c, socketChannel);
+ c.enableSSL(tlsByteChannel);
+ }
+ return c;
+ }
+
+ /**
+ * Creates a TLS Byte Channel instance using the specified LDAP
+ * client connection and socket channel.
+ *
+ * @param c The client connection to use in the creation.
+ * @param socketChannel The socket channel to use in the creation.
+ * @return A TLS Byte Channel instance.
+ * @throws DirectoryException If the channel cannot be created.
+ */
+ public TLSByteChannel
+ getTLSByteChannel(LDAPClientConnection c, SocketChannel socketChannel)
+ throws DirectoryException {
+ return(TLSByteChannel.getTLSByteChannel(currentConfig, c,
+ sslContext,
+ socketChannel));
+ }
+
+ private void configSSL(LDAPConnectionHandlerCfg config)
+ throws DirectoryException {
+ ResultCode resCode = DirectoryServer.getServerErrorResultCode();
+ try {
+ String alias = config.getSSLCertNickname();
+ protocol += "+SSL";
+ DN keyMgrDN = config.getKeyManagerProviderDN();
+ DN trustMgrDN = config.getTrustManagerProviderDN();
+ KeyManagerProvider<?> keyManagerProvider =
+ DirectoryServer.getKeyManagerProvider(keyMgrDN);
+ if (keyManagerProvider == null)
+ keyManagerProvider = new NullKeyManagerProvider();
+ TrustManagerProvider<?> trustManagerProvider =
+ DirectoryServer.getTrustManagerProvider(trustMgrDN);
+ if (trustManagerProvider == null)
+ trustManagerProvider = new NullTrustManagerProvider();
+ sslContext = SSLContext.getInstance(SSL_CONTEXT_INSTANCE_NAME);
+ if (alias == null) {
+ sslContext.init(keyManagerProvider.getKeyManagers(),
+ trustManagerProvider.getTrustManagers(), null);
+ } else {
+ sslContext.init(SelectableCertificateKeyManager.wrap(
+ keyManagerProvider.getKeyManagers(), alias),
+ trustManagerProvider.getTrustManagers(), null);
+ }
+ } catch (NoSuchAlgorithmException nsae) {
+ if (debugEnabled())
+ TRACER.debugCaught(DebugLogLevel.ERROR, nsae);
+ Message message = ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.
+ get(getExceptionMessage(nsae));
+ throw new DirectoryException(resCode, message, nsae);
+ } catch (KeyManagementException kme) {
+ if (debugEnabled())
+ TRACER.debugCaught(DebugLogLevel.ERROR, kme);
+ Message message = ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE
+ .get(getExceptionMessage(kme));
+ throw new DirectoryException(resCode, message, kme);
+ } catch (DirectoryException de) {
+ if (debugEnabled())
+ TRACER.debugCaught(DebugLogLevel.ERROR, de);
+ Message message = ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE
+ .get(getExceptionMessage(de));
+ throw new DirectoryException(resCode, message, de);
+ }
+ }
+
}
--
Gitblit v1.10.0