You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2020/02/20 10:26:53 UTC
[cxf] 01/02: Prevent RMI registry rebind (#641)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3.3.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 98ec361acd390483005de12ca3b10cf49cbdcf8a
Author: Jonathan Gallimore <jo...@jrg.me.uk>
AuthorDate: Thu Feb 20 10:25:11 2020 +0000
Prevent RMI registry rebind (#641)
* Prevent registry rebind
* Add the RMI server when not running threaded
* Update MBServerConnectorFactory.java
* Add compiler option for Java 11. Will look to see if there's a way to avoid the use of sun.rmi.registry altogether
* Identify the lookup name from the JMX URL
* Adding unit test for getBindingName()
* Re-instating test removed by mistake
Co-authored-by: Colm O hEigeartaigh <co...@users.noreply.github.com>
(cherry picked from commit 543de65106515538ecaef8b57c554e88a7bda0d1)
---
parent/pom.xml | 5 +-
rt/management/pom.xml | 3 +-
.../management/jmx/MBServerConnectorFactory.java | 102 ++++++++++++++++++---
.../jmx/MBServerConnectorFactoryTest.java | 55 +++++++++++
4 files changed, 149 insertions(+), 16 deletions(-)
diff --git a/parent/pom.xml b/parent/pom.xml
index b035441..400d332 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -2813,7 +2813,10 @@
<configuration>
<showDeprecation>${cxf.compile.show.deprecation}</showDeprecation>
<showWarnings>true</showWarnings>
- <compilerArgument>${cxf.compile.flags}</compilerArgument>
+ <compilerArgs>
+ <arg>${cxf.compile.flags}</arg>
+ <arg>--add-exports</arg><arg>java.rmi/sun.rmi.registry=ALL-UNNAMED</arg>
+ </compilerArgs>
</configuration>
</plugin>
<plugin>
diff --git a/rt/management/pom.xml b/rt/management/pom.xml
index cc042e3..faff4a7 100644
--- a/rt/management/pom.xml
+++ b/rt/management/pom.xml
@@ -34,7 +34,8 @@
<cxf.module.name>org.apache.cxf.management</cxf.module.name>
<cxf.osgi.import>
javax.xml.bind*;version="${cxf.osgi.javax.bind.version}",
- javax.annotation*;version="${cxf.osgi.javax.annotation.version}"
+ javax.annotation*;version="${cxf.osgi.javax.annotation.version}",
+ sun.rmi*;resolution:=optional
</cxf.osgi.import>
</properties>
<dependencies>
diff --git a/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java b/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java
index 6906333..5eb7059 100644
--- a/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java
+++ b/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java
@@ -20,7 +20,13 @@
package org.apache.cxf.management.jmx;
import java.io.IOException;
-import java.rmi.registry.LocateRegistry;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -28,8 +34,9 @@ import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
import org.apache.cxf.common.logging.LogUtils;
@@ -57,6 +64,10 @@ public final class MBServerConnectorFactory {
private static JMXConnectorServer connectorServer;
+ private static Remote remoteServerStub;
+
+ private static RMIJRMPServerImpl rmiServer;
+
private static class MBServerConnectorFactoryHolder {
private static final MBServerConnectorFactory INSTANCE =
new MBServerConnectorFactory();
@@ -71,7 +82,7 @@ public final class MBServerConnectorFactory {
}
- private int getURLLocalHostPort(String url) {
+ static int getServerPort(final String url) {
int portStart = url.indexOf("localhost") + 10;
int portEnd;
int port = 0;
@@ -127,29 +138,24 @@ public final class MBServerConnectorFactory {
}
// Create the JMX service URL.
- JMXServiceURL url = new JMXServiceURL(serviceUrl);
+ final JMXServiceURL url = new JMXServiceURL(serviceUrl);
// if the URL is localhost, start up an Registry
if (serviceUrl.indexOf("localhost") > -1
&& url.getProtocol().compareToIgnoreCase("rmi") == 0) {
try {
- int port = getURLLocalHostPort(serviceUrl);
- try {
- LocateRegistry.createRegistry(port);
- } catch (Exception ex) {
- // the registry may had been created
- LocateRegistry.getRegistry(port);
- }
+ int port = getRegistryPort(serviceUrl);
+ new JmxRegistry(port, getBindingName(url));
} catch (Exception ex) {
LOG.log(Level.SEVERE, "CREATE_REGISTRY_FAULT_MSG", new Object[]{ex});
}
}
- // Create the connector server now.
- connectorServer =
- JMXConnectorServerFactory.newJMXConnectorServer(url, environment, server);
+ rmiServer = new RMIJRMPServerImpl(getServerPort(serviceUrl), null, null, environment);
+ // Create the connector server now.
+ connectorServer = new RMIConnectorServer(url, environment, rmiServer, server);
if (threaded) {
// Start the connector server asynchronously (in a separate thread).
@@ -157,6 +163,7 @@ public final class MBServerConnectorFactory {
public void run() {
try {
connectorServer.start();
+ remoteServerStub = rmiServer.toStub();
} catch (IOException ex) {
LOG.log(Level.SEVERE, "START_CONNECTOR_FAILURE_MSG", new Object[]{ex});
}
@@ -169,6 +176,7 @@ public final class MBServerConnectorFactory {
} else {
// Start the connector server in the same thread.
connectorServer.start();
+ remoteServerStub = rmiServer.toStub();
}
if (LOG.isLoggable(Level.INFO)) {
@@ -176,6 +184,38 @@ public final class MBServerConnectorFactory {
}
}
+ static int getRegistryPort(final String url) {
+ int serverStart = url.indexOf("/jndi/rmi://");
+ final String serverPart = url.substring(serverStart + 12);
+ int portStart = serverPart.indexOf(':') + 1;
+
+ int portEnd;
+ int port = 0;
+ if (portStart > 0) {
+ portEnd = indexNotOfNumber(serverPart, portStart);
+ if (portEnd > portStart) {
+ final String portString = serverPart.substring(portStart, portEnd);
+ port = Integer.parseInt(portString);
+ }
+ }
+ return port;
+ }
+
+ protected static String getBindingName(final JMXServiceURL jmxServiceURL) {
+ final String urlPath = jmxServiceURL.getURLPath();
+
+ try {
+ if (urlPath.startsWith("/jndi/")) {
+ return new URI(urlPath.substring(6)).getPath()
+ .replaceAll("^/+", "").replaceAll("/+$", "");
+ }
+ } catch (URISyntaxException e) {
+ // ignore
+ }
+
+ return "jmxrmi"; // use the default
+ }
+
public void destroy() throws IOException {
connectorServer.stop();
if (LOG.isLoggable(Level.INFO)) {
@@ -183,4 +223,38 @@ public final class MBServerConnectorFactory {
}
}
+ /*
+ * Better to use the internal API than re-invent the wheel.
+ */
+ @SuppressWarnings("restriction")
+ private class JmxRegistry extends sun.rmi.registry.RegistryImpl {
+ private final String lookupName;
+
+ JmxRegistry(final int port, final String lookupName) throws RemoteException {
+ super(port);
+ this.lookupName = lookupName;
+ }
+
+ @Override
+ public Remote lookup(String s) throws RemoteException, NotBoundException {
+ return lookupName.equals(s) ? remoteServerStub : null;
+ }
+
+ @Override
+ public void bind(String s, Remote remote) throws RemoteException, AlreadyBoundException, AccessException {
+ }
+
+ @Override
+ public void unbind(String s) throws RemoteException, NotBoundException, AccessException {
+ }
+
+ @Override
+ public void rebind(String s, Remote remote) throws RemoteException, AccessException {
+ }
+
+ @Override
+ public String[] list() throws RemoteException {
+ return new String[] {lookupName};
+ }
+ }
}
diff --git a/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java b/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java
new file mode 100644
index 0000000..468ec0c
--- /dev/null
+++ b/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.management.jmx;
+
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class MBServerConnectorFactoryTest {
+
+ @Test
+ public void testGetServerPort() throws Exception {
+ Assert.assertEquals(9914, MBServerConnectorFactory.getServerPort(
+ "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"));
+
+ Assert.assertEquals(10002, MBServerConnectorFactory.getServerPort(
+ "service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi"));
+ }
+
+ @Test
+ public void testGetRegistryPort() throws Exception {
+ Assert.assertEquals(9914, MBServerConnectorFactory.getRegistryPort(
+ "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"));
+
+ Assert.assertEquals(10001, MBServerConnectorFactory.getRegistryPort(
+ "service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi"));
+ }
+
+ @Test
+ public void testGetBindingName() throws Exception {
+ Assert.assertEquals("jmxrmi", MBServerConnectorFactory.getBindingName(
+ new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi")));
+
+ Assert.assertEquals("cxf-jmxrmi", MBServerConnectorFactory.getBindingName(
+ new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9913/cxf-jmxrmi")));
+ }
+}
\ No newline at end of file