From 9fc1e30fd3b481843e5905b93ad07f767b011967 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Thu, 21 Sep 2006 07:57:07 +0000
Subject: [PATCH] This wrapper will allow to set trust store manager to validate server certificate. (Issue #674: JMX over SSL does not work)
---
opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/OpendsJmxConnector.java | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 379 insertions(+), 0 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/OpendsJmxConnector.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/OpendsJmxConnector.java
new file mode 100644
index 0000000..db5e71c
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/OpendsJmxConnector.java
@@ -0,0 +1,379 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.protocols.jmx;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanServerConnection;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.security.auth.Subject;
+
+/**
+ * Wrapper class for the JMX's RMI connector. This class has the exact same
+ * functionnalities but maintain inner variables which are used during the
+ * connection phase.
+ * <p>
+ * Note that the javadoc has been copied from the
+ * javax.management.remote.JMXConnector interface.
+ */
+public class OpendsJmxConnector implements JMXConnector
+
+{
+
+ /**
+ * the wrapped JMX RMI connector.
+ */
+ private JMXConnector jmxc = null;
+
+ /**
+ * the connection environment set at creation.
+ */
+ private Map<String,Object> environment = null;
+
+ /**
+ * the JMX Service URL.
+ */
+ private JMXServiceURL serviceURL = null;
+
+ /**
+ * the host to connect to.
+ */
+ private String serverHostname = null;
+
+
+
+ /**
+ * Creates a connector client for the connector server at the
+ * given host and port. The resultant client is not connected until its
+ * connect method is called.
+ *
+ * @param serverHostname the target server hostname
+ *
+ * @param serverPort the target server port
+ *
+ * @param environment a set of attributes to determine how the
+ * connection is made. This parameter can be null. Keys in this
+ * map must be Strings. The appropriate type of each associated
+ * value depends on the attribute. The contents of
+ * <code>environment</code> are not changed by this call.
+ *
+ * @exception IOException if the connector client cannot be made
+ * because of a communication problem.
+ *
+ */
+ public OpendsJmxConnector(String serverHostname, int serverPort,
+ Map<String,Object> environment) throws IOException
+ {
+ serviceURL = new JMXServiceURL(
+ "service:jmx:rmi:///jndi/rmi://" + serverHostname + ":" + serverPort
+ + "/org.opends.server.protocols.jmx.client-unknown");
+
+ this.jmxc = JMXConnectorFactory.newJMXConnector(serviceURL, environment);
+ this.serverHostname = serverHostname;
+ this.environment = environment ;
+ }
+// /**
+// * Sets this connector's connection environment.
+// *
+// * @param environment the new connection env
+// */
+// public void setConnectionEnv(Map connectionEnv)
+// {
+// this.environment = environment;
+// }
+
+ /**
+ * Returns the connection environment.
+ *
+ * @return Map the connection environment used by new connections
+ */
+ public Map getConnectionEnv()
+ {
+ return environment;
+ }
+
+ /**
+ * Establishes the connection to the connector server. This method is
+ * equivalent to connect(null).
+ *
+ * @throws IOException
+ * if the connection could not be made because of a communication
+ * problem.
+ * @throws SecurityException
+ * if the connection could not be made for security reasons.
+ */
+ public void connect() throws IOException, SecurityException
+ {
+ this.connect(null);
+ }
+
+ /**
+ * Establishes the connection to the connector server. If connect has
+ * already been called successfully on this object, calling it again has
+ * no effect. If, however, close() was called after connect, the new
+ * connect will throw an IOException. Otherwise, either connect has never
+ * been called on this object, or it has been called but produced an
+ * exception. Then calling connect will attempt to establish a connection
+ * to the connector server.
+ *
+ * @param env
+ * the properties of the connection. Properties in this map
+ * override properties in the map specified when the JMXConnector
+ * was created, if any. This parameter can be null, which is
+ * equivalent to an empty map.
+ * @throws IOException
+ * if the connection could not be made because of a communication
+ * problem.
+ * @throws SecurityException -
+ * if the connection could not be made for security reasons.
+ */
+ 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);
+ }
+
+ /**
+ * Returns an MBeanServerConnection object representing a remote MBean
+ * server. For a given JMXConnector, two successful calls to this method
+ * will usually return the same MBeanServerConnection object, though this
+ * is not required. For each method in the returned
+ * MBeanServerConnection, calling the method causes the corresponding
+ * method to be called in the remote MBean server. The value returned by
+ * the MBean server method is the value returned to the client. If the
+ * MBean server method produces an Exception, the same Exception is seen
+ * by the client. If the MBean server method, or the attempt to call it,
+ * produces an Error, the Error is wrapped in a JMXServerErrorException,
+ * which is seen by the client. Calling this method is equivalent to
+ * calling getMBeanServerConnection(null) meaning that no delegation
+ * subject is specified and that all the operations called on the
+ * MBeanServerConnection must use the authenticated subject, if any.
+ *
+ * @return an object that implements the MBeanServerConnection interface
+ * by forwarding its methods to the remote MBean server.
+ * @throws IOException -
+ * if a valid MBeanServerConnection cannot be created, for
+ * instance because the connection to the remote MBean server has
+ * not yet been established (with the connect method), or it has
+ * been closed, or it has broken.
+ */
+ public MBeanServerConnection getMBeanServerConnection() throws IOException
+ {
+ return jmxc.getMBeanServerConnection();
+ }
+
+ /**
+ * Returns an MBeanServerConnection object representing a remote MBean
+ * server on which operations are performed on behalf of the supplied
+ * delegation subject. For a given JMXConnector and Subject, two
+ * successful calls to this method will usually return the same
+ * MBeanServerConnection object, though this is not required. For each
+ * method in the returned MBeanServerConnection, calling the method
+ * causes the corresponding method to be called in the remote MBean
+ * server on behalf of the given delegation subject instead of the
+ * authenticated subject. The value returned by the MBean server method
+ * is the value returned to the client. If the MBean server method
+ * produces an Exception, the same Exception is seen by the client. If
+ * the MBean server method, or the attempt to call it, produces an Error,
+ * the Error is wrapped in a JMXServerErrorException, which is seen by
+ * the client.
+ *
+ * @param delegationSubject
+ * the Subject on behalf of which requests will be performed. Can
+ * be null, in which case requests will be performed on behalf of
+ * the authenticated Subject, if any.
+ * @return an object that implements the MBeanServerConnection interface
+ * by forwarding its methods to the remote MBean server on behalf
+ * of a given delegation subject.
+ * @throws IOException
+ * if a valid MBeanServerConnection cannot be created, for
+ * instance because the connection to the remote MBean server has
+ * not yet been established (with the connect method), or it has
+ * been closed, or it has broken.
+ */
+ public MBeanServerConnection getMBeanServerConnection(
+ Subject delegationSubject) throws IOException
+ {
+ return jmxc.getMBeanServerConnection(delegationSubject);
+ }
+
+ /**
+ * Closes the client connection to its server. Any ongoing or new request
+ * using the MBeanServerConnection returned by getMBeanServerConnection()
+ * will get an IOException. If close has already been called successfully
+ * on this object, calling it again has no effect. If close has never
+ * been called, or if it was called but produced an exception, an attempt
+ * will be made to close the connection. This attempt can succeed, in
+ * which case close will return normally, or it can generate an
+ * exception. Closing a connection is a potentially slow operation. For
+ * example, if the server has crashed, the close operation might have to
+ * wait for a network protocol timeout. Callers that do not want to block
+ * in a close operation should do it in a separate thread.
+ *
+ * @throws IOException
+ * if the connection cannot be closed cleanly. If this exception
+ * is thrown, it is not known whether the server end of the
+ * connection has been cleanly closed.
+ */
+ public void close() throws IOException
+ {
+ jmxc.close();
+ }
+
+ /**
+ * Adds a listener to be informed of changes in connection status. The
+ * listener will receive notifications of type JMXConnectionNotification.
+ * An implementation can send other types of notifications too. Any
+ * number of listeners can be added with this method. The same listener
+ * can be added more than once with the same or different values for the
+ * filter and handback. There is no special treatment of a duplicate
+ * entry. For example, if a listener is registered twice with no filter,
+ * then its handleNotification method will be called twice for each
+ * notification.
+ *
+ * @param listener
+ * a listener to receive connection status notifications.
+ * @param filter
+ * a filter to select which notifications are to be delivered to
+ * the listener, or null if all notifications are to be delivered.
+ * @param handback
+ * an object to be given to the listener along with each
+ * notification. Can be null.
+ * @throws NullPointerException
+ * if listener is null.
+ */
+ public void addConnectionNotificationListener(
+ NotificationListener listener, NotificationFilter filter,
+ Object handback) throws NullPointerException
+ {
+ jmxc.addConnectionNotificationListener(listener, filter, handback);
+ }
+
+ /**
+ * Removes a listener from the list to be informed of changes in status.
+ * The listener must previously have been added. If there is more than
+ * one matching listener, all are removed.
+ *
+ * @param listener -
+ * a listener to receive connection status notifications.
+ * @throws NullPointerException
+ * if listener is null.
+ * @throws ListenerNotFoundException
+ * if the listener is not registered with this JMXConnector.
+ */
+ public void removeConnectionNotificationListener(
+ NotificationListener listener) throws ListenerNotFoundException,
+ NullPointerException
+ {
+ jmxc.removeConnectionNotificationListener(listener);
+ }
+
+ /**
+ * Removes a listener from the list to be informed of changes in status.
+ * The listener must previously have been added with the same three
+ * parameters. If there is more than one matching listener, only one is
+ * removed.
+ *
+ * @param l
+ * a listener to receive connection status notifications.
+ * @param f
+ * a filter to select which notifications are to be delivered to
+ * the listener. Can be null. handback - an object to be given to
+ * the listener along with each notification. Can be null.
+ * @param handback
+ * an object to be given to the listener along with each
+ * notification. Can be null.
+ * @throws ListenerNotFoundException
+ * if the listener is not registered with this JMXConnector, or
+ * is not registered with the given filter and handback.
+ */
+ public void removeConnectionNotificationListener(
+ NotificationListener l, NotificationFilter f, Object handback)
+ throws ListenerNotFoundException
+ {
+ jmxc.removeConnectionNotificationListener(l, f, handback);
+ }
+
+ /**
+ * Gets this connection's ID from the connector server. For a given
+ * connector server, every connection will have a unique id which does
+ * not change during the lifetime of the connection.
+ *
+ * @return the unique ID of this connection. This is the same as the ID
+ * that the connector server includes in its
+ * JMXConnectionNotifications. The package description describes
+ * the conventions for connection IDs.
+ * @throws IOException
+ * if the connection ID cannot be obtained, for instance because
+ * the connection is closed or broken.
+ */
+ public String getConnectionId() throws IOException
+ {
+ return jmxc.getConnectionId();
+ }
+
+ /**
+ * Update if necessary the credentials of the given map using
+ * information coming from the map given when the connector was created.
+ * This method is called from the connect method when it has received
+ * a non null map holding potentially new credentials. It calls this
+ * method BEFORE actually trying to connect to the server.
+ *
+ * @param Map given to the connect method
+ */
+ private void updateCredentials(Map env) throws IOException
+ {
+ // credential to update ??
+ if (!env.containsKey(JMXConnector.CREDENTIALS))
+ {
+ // NO : nothing to update
+ return;
+ }
+ else
+ {
+ Object cred = env.get(JMXConnector.CREDENTIALS);
+ environment.put(JMXConnector.CREDENTIALS, cred);
+ }
+ }
+}
--
Gitblit v1.10.0