From 8e8b82700e52b07c746f9acbd82fb8038d9c3543 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 05 Mar 2013 12:00:24 +0000
Subject: [PATCH] OPENDJ-764 ldapsearch etc does not try all dns entries
---
opends/src/server/org/opends/server/tools/SSLConnectionFactory.java | 34 ++++++
opends/src/server/org/opends/server/tools/LDAPConnection.java | 224 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 217 insertions(+), 41 deletions(-)
diff --git a/opends/src/server/org/opends/server/tools/LDAPConnection.java b/opends/src/server/org/opends/server/tools/LDAPConnection.java
index 8a2729b..c1d5688 100644
--- a/opends/src/server/org/opends/server/tools/LDAPConnection.java
+++ b/opends/src/server/org/opends/server/tools/LDAPConnection.java
@@ -23,41 +23,45 @@
*
*
* Copyright 2009-2010 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.tools;
-import org.opends.messages.Message;
-
-import java.io.PrintStream;
import java.io.IOException;
+import java.io.PrintStream;
import java.net.ConnectException;
+import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
-import org.opends.server.controls.*;
+import org.opends.messages.Message;
+import org.opends.server.controls.AuthorizationIdentityResponseControl;
+import org.opends.server.controls.PasswordExpiringControl;
+import org.opends.server.controls.PasswordPolicyErrorType;
+import org.opends.server.controls.PasswordPolicyResponseControl;
+import org.opends.server.controls.PasswordPolicyWarningType;
+import org.opends.server.loggers.debug.DebugLogger;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.loggers.debug.TraceSettings;
import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp;
import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.UnbindRequestProtocolOp;
+import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.loggers.debug.DebugLogger;
-import org.opends.server.loggers.debug.TraceSettings;
-import static org.opends.messages.CoreMessages.
- INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR;
+import static org.opends.messages.CoreMessages.*;
import static org.opends.messages.ToolMessages.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.protocols.ldap.LDAPResultCode.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
-import static org.opends.server.protocols.ldap.LDAPResultCode.*;
@@ -195,20 +199,15 @@
{
try
{
- startTLSSocket = new Socket(hostName, portNumber);
+ startTLSSocket = createSocket();
ldapWriter = new LDAPWriter(startTLSSocket);
ldapReader = new LDAPReader(startTLSSocket);
- } catch(UnknownHostException uhe)
+ }
+ catch (LDAPConnectionException e)
{
- Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
- throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
- uhe);
- } catch(ConnectException ce)
- {
- Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
- throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
- ce);
- } catch(Exception ex)
+ throw e;
+ }
+ catch (Exception ex)
{
if (debugEnabled())
{
@@ -259,21 +258,7 @@
connectionOptions.getSSLConnectionFactory();
try
{
- if(sslConnectionFactory != null)
- {
- if(connectionOptions.useStartTLS())
- {
- // Use existing socket.
- socket = sslConnectionFactory.createSocket(startTLSSocket, hostName,
- portNumber, true);
- } else
- {
- socket = sslConnectionFactory.createSocket(hostName, portNumber);
- }
- } else
- {
- socket = new Socket(hostName, portNumber);
- }
+ socket = createSSLOrBasicSocket(startTLSSocket, sslConnectionFactory);
ldapWriter = new LDAPWriter(socket);
ldapReader = new LDAPReader(socket);
} catch(UnknownHostException uhe)
@@ -532,6 +517,169 @@
}
/**
+ * Creates a socket using the hostName and portNumber encapsulated in the
+ * current object. For each IP address associated to this host name,
+ * createSocket() will try to open a socket and it will return the first
+ * socket for which we successfully establish a connection.
+ * <p>
+ * This method can never return null because it will receive
+ * UnknownHostException before and then throw LDAPConnectionException.
+ * </p>
+ *
+ * @return a new {@link Socket}.
+ * @throws LDAPConnectionException
+ * if any exception occurs including UnknownHostException
+ */
+ private Socket createSocket() throws LDAPConnectionException
+ {
+ ConnectException ce = null;
+ try
+ {
+ for (InetAddress inetAddress : InetAddress.getAllByName(hostName))
+ {
+ try
+ {
+ return new Socket(inetAddress, portNumber);
+ }
+ catch (ConnectException ce2)
+ {
+ if (ce == null)
+ {
+ ce = ce2;
+ }
+ }
+ }
+ }
+ catch (UnknownHostException uhe)
+ {
+ Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
+ throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
+ uhe);
+ }
+ catch (Exception ex)
+ {
+ // if we get there, something went awfully wrong while creatng one socket,
+ // no need to continue the for loop.
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ throw new LDAPConnectionException(Message.raw(ex.getMessage()), ex);
+ }
+ if (ce != null)
+ {
+ Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
+ throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
+ ce);
+ }
+ return null;
+ }
+
+ /**
+ * Creates an SSL socket using the hostName and portNumber encapsulated in the
+ * current object. For each IP address associated to this host name,
+ * createSSLSocket() will try to open a socket and it will return the first
+ * socket for which we successfully establish a connection.
+ * <p>
+ * This method can never return null because it will receive
+ * UnknownHostException before and then throw LDAPConnectionException.
+ * </p>
+ *
+ * @return a new {@link Socket}.
+ * @throws LDAPConnectionException
+ * if any exception occurs including UnknownHostException
+ */
+ private Socket createSSLSocket(SSLConnectionFactory sslConnectionFactory)
+ throws SSLConnectionException, LDAPConnectionException
+ {
+ ConnectException ce = null;
+ try
+ {
+ for (InetAddress inetAddress : InetAddress.getAllByName(hostName))
+ {
+ try
+ {
+ return sslConnectionFactory.createSocket(inetAddress, portNumber);
+ }
+ catch (ConnectException ce2)
+ {
+ if (ce == null)
+ {
+ ce = ce2;
+ }
+ }
+ }
+ }
+ catch (UnknownHostException uhe)
+ {
+ Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
+ throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
+ uhe);
+ }
+ catch (Exception ex)
+ {
+ // if we get there, something went awfully wrong while creatng one socket,
+ // no need to continue the for loop.
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ throw new LDAPConnectionException(Message.raw(ex.getMessage()), ex);
+ }
+ if (ce != null)
+ {
+ Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
+ throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
+ ce);
+ }
+ return null;
+ }
+
+ /**
+ * Creates an SSL socket or a normal/basic socket using the hostName and
+ * portNumber encapsulated in the current object, or with the passed in socket
+ * if it needs to use start TLS.
+ *
+ * @param startTLSSocket
+ * the Socket to use if it needs to use start TLS.
+ * @param sslConnectionFactory
+ * the {@link SSLConnectionFactory} for creating SSL sockets
+ * @return a new {@link Socket}
+ * @throws SSLConnectionException
+ * if the SSL socket creation fails
+ * @throws LDAPConnectionException
+ * if any other error occurs
+ */
+ private Socket createSSLOrBasicSocket(Socket startTLSSocket,
+ SSLConnectionFactory sslConnectionFactory) throws SSLConnectionException,
+ LDAPConnectionException
+ {
+ if (sslConnectionFactory == null)
+ {
+ return createSocket();
+ }
+ else if (!connectionOptions.useStartTLS())
+ {
+ return createSSLSocket(sslConnectionFactory);
+ }
+ else
+ {
+ try
+ {
+ // Use existing socket.
+ return sslConnectionFactory.createSocket(startTLSSocket, hostName,
+ portNumber, true);
+ }
+ catch (IOException e)
+ {
+ Message msg = INFO_RESULT_CLIENT_SIDE_CONNECT_ERROR.get();
+ throw new LDAPConnectionException(msg, CLIENT_SIDE_CONNECT_ERROR, null,
+ e);
+ }
+ }
+ }
+
+ /**
* Close the underlying ASN1 reader and writer, optionally sending an unbind
* request before disconnecting.
*
diff --git a/opends/src/server/org/opends/server/tools/SSLConnectionFactory.java b/opends/src/server/org/opends/server/tools/SSLConnectionFactory.java
index 270a055..67ef447 100644
--- a/opends/src/server/org/opends/server/tools/SSLConnectionFactory.java
+++ b/opends/src/server/org/opends/server/tools/SSLConnectionFactory.java
@@ -23,16 +23,19 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.tools;
import java.io.FileInputStream;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Provider;
+
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@@ -42,13 +45,13 @@
import javax.net.ssl.X509TrustManager;
import org.opends.server.extensions.BlindTrustManagerProvider;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.DebugLogLevel;
import org.opends.server.util.ExpirationCheckTrustManager;
import org.opends.server.util.SelectableCertificateKeyManager;
import static org.opends.messages.ToolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
/**
@@ -161,7 +164,6 @@
{
if(sslSocketFactory == null)
{
-
throw new SSLConnectionException(
ERR_TOOLS_SSL_CONNECTION_NOT_INITIALIZED.get());
}
@@ -169,6 +171,32 @@
}
/**
+ * Create the SSL socket connection to the specified host.
+ *
+ * @param host
+ * The address of the system to which the connection should be
+ * established.
+ * @param portNumber
+ * The port number to which the connection should be established.
+ * @return The SSL socket established to the specified host.
+ * @throws SSLConnectionException
+ * If a problem occurs while performing SSL negotiation.
+ * @throws IOException
+ * If a problem occurs while attempting to communicate with the
+ * server.
+ */
+ public Socket createSocket(InetAddress host, int portNumber)
+ throws SSLConnectionException, IOException
+ {
+ if (sslSocketFactory == null)
+ {
+ throw new SSLConnectionException(ERR_TOOLS_SSL_CONNECTION_NOT_INITIALIZED
+ .get());
+ }
+ return sslSocketFactory.createSocket(host, portNumber);
+ }
+
+ /**
* Create the SSL socket connection to the specified host layered over
* an existing socket.
*
--
Gitblit v1.10.0