From 9066892d29000b912b1d83483719fc4d85dee0d8 Mon Sep 17 00:00:00 2001
From: Patrick Diligent <patrick.diligent@forgerock.com>
Date: Mon, 23 Mar 2015 03:16:49 +0000
Subject: [PATCH] OPENDJ-1842 (CR-6359) Using SSL with JMX doesn't work

---
 /dev/null                                                                                  |  338 --------------------------------------------------------
 opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/OpendsJmxConnector.java |   12 --
 opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java       |    5 
 3 files changed, 3 insertions(+), 352 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/DirectoryRMIClientSocketFactory.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/DirectoryRMIClientSocketFactory.java
deleted file mode 100644
index e1b092f..0000000
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/DirectoryRMIClientSocketFactory.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2014-2015 ForgeRock AS
- */
-package org.opends.server.protocols.jmx;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.Socket;
-import java.rmi.server.RMIClientSocketFactory;
-import java.util.Map;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import org.forgerock.i18n.slf4j.LocalizedLogger;
-
-/**
- * A <code>DirectoryRMIClientSocketFactory</code> instance is used by the
- * RMI runtime in order to obtain client sockets for RMI calls via SSL.
- * <p>
- * This class implements <code>RMIClientSocketFactory</code> over the
- * Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocols.
- * </p>
- */
-public class DirectoryRMIClientSocketFactory implements
-    RMIClientSocketFactory, Serializable
-{
-  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
-
-  /**
-   * The serial version identifier required to satisfy the compiler because
-   * this class implements the <CODE>java.io.Serializable</CODE> interface.
-   * This value was generated using the <CODE>serialver</CODE> command-line
-   * utility included with the Java SDK.
-   */
-  private static final long serialVersionUID = -6701450600497520362L;
-
-  /**
-   * the static thread-local connection environment used by the RMI
-   * client to configure this factory.
-   */
-  private static InheritableThreadLocal<Map> tlMapConnectionEnv =
-    new InheritableThreadLocal<Map>();
-
-  /**
-   * The static thread-local target server hostname used by the RMI
-   * client to configure this factory.
-   */
-  private static InheritableThreadLocal<String> tlStrServerHostname =
-    new InheritableThreadLocal<String>();
-
-  /**
-   * the connection mode. <code>true</code> indicates that the client
-   * will be authenticated by its certificate (SSL protocol).
-   * <code>false</code> indicates that we have to perform an lDAP
-   * authentication
-   */
-  private final boolean needClientCertificate;
-
-  /**
-   * the ssl socket factory (do not serialize).
-   */
-  private transient SSLSocketFactory sslSocketFactory;
-
-  /**
-   * the host to connect to (do not serialize).
-   */
-  private transient String serverHostname;
-
-  /**
-   * Constructs a new <code>DirectoryRMIClientSocketFactory</code>.
-   *
-   * @param wellknown
-   *            <code>true</code> for wellknown, <code>false</code>
-   *            otherwise
-   */
-  public DirectoryRMIClientSocketFactory(boolean wellknown)
-  {
-    this.needClientCertificate = wellknown;
-
-    // We don't force the initialization of the SSLSocketFactory
-    // at construction time - because the RMI client socket factory is
-    // created on the server side, where that initialization is a
-    // priori
-    // meaningless, unless both server and client run in the same JVM.
-    // So contrarily to what we do for the server side, the
-    // initialization
-    // of the SSLSocketFactory will be delayed until the first time
-    // createSocket() is called.
-  }
-
-  /**
-   * Sets the thread-local connection environment.
-   *
-   * @param connectionEnv the new connection env
-   */
-  public static void setConnectionEnv(Map connectionEnv)
-  {
-    tlMapConnectionEnv.set(connectionEnv);
-  }
-
-  /**
-   * Returns the thread-local connection environment.
-   *
-   * @return Map the connection environment used by new connections
-   */
-  public static Map getConnectionEnv()
-  {
-    return tlMapConnectionEnv.get();
-  }
-
-  /**
-   * Sets the thread-local target server hostname.
-   *
-   * @param serverHostname
-   *            the target server hostname
-   */
-  public static void setServerHostname(String serverHostname)
-  {
-    tlStrServerHostname.set(serverHostname);
-  }
-
-  /**
-   * Returns the thread-local target server hostname.
-   *
-   * @return String the target server hostname
-   */
-  public static String getServerHostname()
-  {
-    return tlStrServerHostname.get();
-  }
-
-  /**
-   * Returns the connection mode as configured at construction time.
-   *
-   * @return boolean <code>true</code> for wellknown,
-   *         <code>false</code> otherwise
-   */
-  public boolean getNeedClientCertificate()
-  {
-    return needClientCertificate;
-  }
-
-  /**
-   * Creates an SSL socket configured with the right trust stores and the
-   * right target host.
-   * <p>
-   * The keystore and truststore used come from client configuration and
-   * depend on the connection mode specified at construction time.
-   * <p>
-   * The target host is the host specified except if a different host was
-   * specified in the connection environment.
-   *
-   * @param host
-   *            the target host as known by the RMI stack
-   * @param port
-   *            the target port number
-   * @return an SSL socket
-   *
-   * @throws IOException
-   *             if an error occurs while configuring the socket
-   */
-  public Socket createSocket(String host, int port) throws IOException
-  {
-    SSLSocketFactory sslSocketFactory = getSSLSocketFactory();
-    String realhost = getRealServerHostname(host);
-    return sslSocketFactory.createSocket(realhost, port);
-  }
-
-  /**
-   * Indicates whether some other object is "equal to" this one.
-   * <p>
-   * Because each RMI client might have its own configuration, we do not
-   * try to optimize anything. Each RMI connector uses its own RMI client
-   * socket factory. In other words, Directory RMI clients never share
-   * the same client socket factory.
-   * </p>
-   *
-   * @param obj
-   *            the reference object with which to compare
-   * @return <code>true</code> if this object is the same as the obj
-   *         argument <code>false</code> otherwise
-   */
-  public boolean equals(Object obj)
-  {
-    return super.equals(obj);
-  }
-
-  /**
-   * Returns a hash code value for this
-   * <code>DirectoryRMIClientSocketFactory</code>.
-   *
-   * @return a hash code value for this
-   *         <code>DirectoryRMIClientSocketFactory</code>
-   */
-  public int hashCode()
-  {
-    return super.hashCode();
-  }
-
-  /**
-   * Returns the real server hostname to connect to.
-   *
-   * @param rmiHostname
-   *            the target hostname as known by RMI stack
-   * @return String the real hostname to connect to
-   * @throws IOException
-   *             if an error occurs
-   */
-  private synchronized String getRealServerHostname(String rmiHostname)
-      throws IOException
-  {
-    if (serverHostname == null)
-    {
-      //
-      // does the client specify another host by
-      // using thread-local static parameter ?
-      serverHostname = getServerHostname();
-
-      //
-      // if not found here, don't look for real host in static
-      // anymore
-      if (serverHostname == null)
-      {
-        serverHostname = "";
-      }
-    }
-
-    if (serverHostname.length() > 0)
-    {
-      return serverHostname;
-    }
-    else
-    {
-      return rmiHostname;
-    }
-  }
-
-  /**
-   * Returns the ssl socket factory used by this RMI client socket
-   * factory.
-   *
-   * @return SSLSocketFactory the ssl socket factory
-   * @throws IOException
-   *             if an error occurs
-   */
-  private synchronized SSLSocketFactory getSSLSocketFactory()
-      throws IOException
-  {
-    if (sslSocketFactory == null)
-    {
-      if (logger.isTraceEnabled())
-      {
-        logger.trace("sslSocketFactory is null, get a new one");
-      }
-
-      // socket factory not yet initialized
-      // initialize the trust
-      Map connectionEnv = getConnectionEnv();
-      TrustManager[] tms = null;
-
-      //
-      // Check if a trust manager array was provided in the
-      // connection
-      // Env. If yes, use it for this SSL Connection
-      if ((connectionEnv != null)
-          && (connectionEnv
-          .containsKey(JmxConnectionHandler.TRUST_MANAGER_ARRAY_KEY)))
-      {
-        try
-        {
-          tms = (TrustManager[]) connectionEnv
-              .get(JmxConnectionHandler.TRUST_MANAGER_ARRAY_KEY);
-        }
-        catch (Exception e)
-        {
-          logger.traceException(e);
-          tms = null;
-        }
-
-        if (tms == null)
-        {
-          //
-          // Why? The value is not invalid ?
-          // Too bad: we raised an exception
-          throw new IOException("invalid type or null value for key ["
-              + JmxConnectionHandler.TRUST_MANAGER_ARRAY_KEY
-              + "] in connection environment : "
-              + connectionEnv
-              .get(JmxConnectionHandler.TRUST_MANAGER_ARRAY_KEY));
-        }
-      }
-
-      // now we have the array of trust Manager
-      // we can initialize the ssl ctx
-      SSLContext ctx = null;
-      try
-      {
-        ctx = SSLContext.getInstance("TLSv1");
-        ctx.init(null, tms, null);
-      }
-      catch (Exception e)
-      {
-        logger.traceException(e);
-        throw new IOException("Unable to initialize SSL context : "
-            + e.getMessage());
-      }
-
-      // create the SSLSocket
-      sslSocketFactory = ctx.getSocketFactory();
-    }
-    return sslSocketFactory;
-  }
-}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/OpendsJmxConnector.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/OpendsJmxConnector.java
index 4446645..f984eb3 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/OpendsJmxConnector.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/OpendsJmxConnector.java
@@ -159,18 +159,6 @@
    */
   public void connect(Map<String,?> env) throws IOException, SecurityException
   {
-    // set the real target hostname
-    DirectoryRMIClientSocketFactory.setServerHostname(serverHostname);
-
-    // configure the thread-local connection environment
-    if (env != null)
-    {
-      // encode credentials if necessary
-      updateCredentials(env);
-    }
-    DirectoryRMIClientSocketFactory.setConnectionEnv(environment);
-
-
     jmxc.connect(env);
   }
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
index e4d3502..7fdf006 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
@@ -42,6 +42,7 @@
 import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXServiceURL;
 import javax.management.remote.rmi.RMIConnectorServer;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
 
 import org.opends.server.api.KeyManagerProvider;
 import org.opends.server.config.JMXMBean;
@@ -279,7 +280,7 @@
       // ---------------------
       // init an ssl context
       // ---------------------
-      DirectoryRMIClientSocketFactory rmiClientSockeyFactory = null;
+      SslRMIClientSocketFactory rmiClientSockeyFactory = null;
       DirectoryRMIServerSocketFactory rmiServerSockeyFactory = null;
       if (jmxConnectionHandler.isUseSSL())
       {
@@ -335,7 +336,7 @@
         // registry
         // ---------------------
         // Set the Client socket factory in the JMX map
-        rmiClientSockeyFactory = new DirectoryRMIClientSocketFactory(false);
+        rmiClientSockeyFactory = new SslRMIClientSocketFactory();
         env.put(
             "jmx.remote.rmi.client.socket.factory",
             rmiClientSockeyFactory);

--
Gitblit v1.10.0