You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/09/05 08:39:47 UTC

karaf git commit: [KARAF-5338] Unable to access the local JMX server on OSX

Repository: karaf
Updated Branches:
  refs/heads/karaf-4.1.x 94f550bd4 -> e7ec18362


[KARAF-5338] Unable to access the local JMX server on OSX


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/e7ec1836
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/e7ec1836
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/e7ec1836

Branch: refs/heads/karaf-4.1.x
Commit: e7ec18362fb1dd8e6836e0f6105541a5cb3afdc3
Parents: 94f550b
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Sep 5 09:22:58 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Sep 5 10:39:39 2017 +0200

----------------------------------------------------------------------
 .../management/ConnectorServerFactory.java      | 341 ++++++++++++++++++-
 1 file changed, 327 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/e7ec1836/management/server/src/main/java/org/apache/karaf/management/ConnectorServerFactory.java
----------------------------------------------------------------------
diff --git a/management/server/src/main/java/org/apache/karaf/management/ConnectorServerFactory.java b/management/server/src/main/java/org/apache/karaf/management/ConnectorServerFactory.java
index d0a20f0..d7ed04f 100644
--- a/management/server/src/main/java/org/apache/karaf/management/ConnectorServerFactory.java
+++ b/management/server/src/main/java/org/apache/karaf/management/ConnectorServerFactory.java
@@ -19,14 +19,22 @@ package org.apache.karaf.management;
 import org.apache.karaf.jaas.config.KeystoreManager;
 import org.apache.karaf.management.internal.MBeanInvocationHandler;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.lang.reflect.Proxy;
 import java.net.BindException;
 import java.net.InetAddress;
+import java.net.NetworkInterface;
 import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImplFactory;
+import java.nio.channels.ServerSocketChannel;
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.security.GeneralSecurityException;
+import java.util.Enumeration;
 import java.util.Map;
 
 import javax.management.JMException;
@@ -38,6 +46,7 @@ import javax.management.remote.JMXServiceURL;
 import javax.management.remote.rmi.RMIConnectorServer;
 import javax.net.ServerSocketFactory;
 import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.rmi.ssl.SslRMIClientSocketFactory;
@@ -50,7 +59,7 @@ public class ConnectorServerFactory {
     private KarafMBeanServerGuard guard;
     private String serviceUrl;
     private String rmiServerHost;
-    private Map environment;
+    private Map<String, Object> environment;
     private ObjectName objectName;
     private boolean threaded = false;
     private boolean daemon = false;
@@ -98,11 +107,11 @@ public class ConnectorServerFactory {
         this.rmiServerHost = rmiServerHost;
     }
 
-    public Map getEnvironment() {
+    public Map<String, Object> getEnvironment() {
         return environment;
     }
 
-    public void setEnvironment(Map environment) {
+    public void setEnvironment(Map<String, Object> environment) {
         this.environment = environment;
     }
 
@@ -229,13 +238,14 @@ public class ConnectorServerFactory {
             throw new IllegalArgumentException("server must be set");
         }
         JMXServiceURL url = new JMXServiceURL(this.serviceUrl);
-        setupKarafRMIServerSocketFactory();
         if ( isClientAuth() ) {
             this.secured = true;
         }
 
         if ( this.secured ) {
-            this.setupSsl();
+            setupSsl();
+        } else {
+            setupKarafRMIServerSocketFactory();
         }
 
         if ( ! AuthenticatorType.PASSWORD.equals( this.authenticatorType ) ) {
@@ -306,9 +316,8 @@ public class ConnectorServerFactory {
     }
 
     private void setupSsl() throws GeneralSecurityException {
-
         SSLServerSocketFactory sssf = keystoreManager.createSSLServerFactory(null, secureProtocol, algorithm, keyStore, keyAlias, trustStore,keyStoreAvailabilityTimeout);
-        RMIServerSocketFactory rssf = new KarafSslRMIServerSocketFactory(sssf, this.isClientAuth(), getRmiServerHost());
+        RMIServerSocketFactory rssf = new KarafSslRMIServerSocketFactory(sssf, isClientAuth(), getRmiServerHost());
         RMIClientSocketFactory rcsf = new SslRMIClientSocketFactory();
         environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rssf);
         environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, rcsf);
@@ -317,8 +326,8 @@ public class ConnectorServerFactory {
     }
 
     private void setupKarafRMIServerSocketFactory() {
-        RMIServerSocketFactory rmiServerSocketFactory = new KarafRMIServerSocketFactory(getRmiServerHost());
-        environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmiServerSocketFactory);
+        RMIServerSocketFactory rssf = new KarafRMIServerSocketFactory(getRmiServerHost());
+        environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rssf);
     }
 
     private static class KarafSslRMIServerSocketFactory implements RMIServerSocketFactory {
@@ -333,9 +342,16 @@ public class ConnectorServerFactory {
         }
 
         public ServerSocket createServerSocket(int port) throws IOException {
-            SSLServerSocket ss = (SSLServerSocket) sssf.createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
-            ss.setNeedClientAuth(clientAuth);
-            return ss;
+            InetAddress host = InetAddress.getByName(rmiServerHost);
+            if (host.isLoopbackAddress()) {
+                final SSLServerSocket ss = (SSLServerSocket) sssf.createServerSocket(port, 50);
+                ss.setNeedClientAuth(clientAuth);
+                return new LocalOnlySSLServerSocket(ss);
+            } else {
+                final SSLServerSocket ss = (SSLServerSocket) sssf.createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
+                ss.setNeedClientAuth(clientAuth);
+                return ss;
+            }
         }
     }
 
@@ -347,10 +363,307 @@ public class ConnectorServerFactory {
         }
 
         public ServerSocket createServerSocket(int port) throws IOException {
-            ServerSocket serverSocket = (ServerSocket) ServerSocketFactory.getDefault().createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
-            return serverSocket;
+            InetAddress host = InetAddress.getByName(rmiServerHost);
+            if (host.isLoopbackAddress()) {
+                final ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(port, 50);
+                return new LocalOnlyServerSocket(ss);
+            } else {
+                final ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
+                return ss;
+            }
+        }
+    }
+
+    private static class LocalOnlyServerSocket extends ServerSocket {
+
+        private final ServerSocket ss;
+
+        public LocalOnlyServerSocket(ServerSocket ss) throws IOException {
+            this.ss = ss;
+        }
+
+        @Override
+        public void bind(SocketAddress endpoint) throws IOException {
+            ss.bind(endpoint);
+        }
+
+        @Override
+        public void bind(SocketAddress endpoint, int backlog) throws IOException {
+            ss.bind(endpoint, backlog);
+        }
+
+        @Override
+        public InetAddress getInetAddress() {
+            return ss.getInetAddress();
+        }
+
+        @Override
+        public int getLocalPort() {
+            return ss.getLocalPort();
+        }
+
+        @Override
+        public SocketAddress getLocalSocketAddress() {
+            return ss.getLocalSocketAddress();
+        }
+
+        @Override
+        public Socket accept() throws IOException {
+            return checkLocal(ss.accept());
+        }
+
+        @Override
+        public void close() throws IOException {
+            ss.close();
+        }
+
+        @Override
+        public ServerSocketChannel getChannel() {
+            return ss.getChannel();
+        }
+
+        @Override
+        public boolean isBound() {
+            return ss.isBound();
+        }
+
+        @Override
+        public boolean isClosed() {
+            return ss.isClosed();
+        }
+
+        @Override
+        public void setSoTimeout(int timeout) throws SocketException {
+            ss.setSoTimeout(timeout);
+        }
+
+        @Override
+        public int getSoTimeout() throws IOException {
+            return ss.getSoTimeout();
+        }
+
+        @Override
+        public void setReuseAddress(boolean on) throws SocketException {
+            ss.setReuseAddress(on);
+        }
+
+        @Override
+        public boolean getReuseAddress() throws SocketException {
+            return ss.getReuseAddress();
+        }
+
+        @Override
+        public String toString() {
+            return ss.toString();
+        }
+
+        @Override
+        public void setReceiveBufferSize(int size) throws SocketException {
+            ss.setReceiveBufferSize(size);
+        }
+
+        @Override
+        public int getReceiveBufferSize() throws SocketException {
+            return ss.getReceiveBufferSize();
+        }
+
+        @Override
+        public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+            ss.setPerformancePreferences(connectionTime, latency, bandwidth);
+        }
+    }
+
+    private static class LocalOnlySSLServerSocket extends SSLServerSocket {
+
+        private final SSLServerSocket ss;
+
+        public LocalOnlySSLServerSocket(SSLServerSocket ss) throws IOException {
+            this.ss = ss;
+        }
+
+        @Override
+        public void bind(SocketAddress endpoint) throws IOException {
+            ss.bind(endpoint);
+        }
+
+        @Override
+        public void bind(SocketAddress endpoint, int backlog) throws IOException {
+            ss.bind(endpoint, backlog);
+        }
+
+        @Override
+        public InetAddress getInetAddress() {
+            return ss.getInetAddress();
+        }
+
+        @Override
+        public int getLocalPort() {
+            return ss.getLocalPort();
+        }
+
+        @Override
+        public SocketAddress getLocalSocketAddress() {
+            return ss.getLocalSocketAddress();
+        }
+
+        @Override
+        public Socket accept() throws IOException {
+            return checkLocal(ss.accept());
+        }
+
+        @Override
+        public void close() throws IOException {
+            ss.close();
+        }
+
+        @Override
+        public ServerSocketChannel getChannel() {
+            return ss.getChannel();
+        }
+
+        @Override
+        public boolean isBound() {
+            return ss.isBound();
+        }
+
+        @Override
+        public boolean isClosed() {
+            return ss.isClosed();
+        }
+
+        @Override
+        public void setSoTimeout(int timeout) throws SocketException {
+            ss.setSoTimeout(timeout);
+        }
+
+        @Override
+        public int getSoTimeout() throws IOException {
+            return ss.getSoTimeout();
+        }
+
+        @Override
+        public void setReuseAddress(boolean on) throws SocketException {
+            ss.setReuseAddress(on);
+        }
+
+        @Override
+        public boolean getReuseAddress() throws SocketException {
+            return ss.getReuseAddress();
+        }
+
+        @Override
+        public String toString() {
+            return ss.toString();
+        }
+
+        @Override
+        public void setReceiveBufferSize(int size) throws SocketException {
+            ss.setReceiveBufferSize(size);
+        }
+
+        @Override
+        public int getReceiveBufferSize() throws SocketException {
+            return ss.getReceiveBufferSize();
+        }
+
+        @Override
+        public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+            ss.setPerformancePreferences(connectionTime, latency, bandwidth);
+        }
+        public String[] getEnabledCipherSuites() {
+            return ss.getEnabledCipherSuites();
+        }
+
+        public void setEnabledCipherSuites(String[] strings) {
+            ss.setEnabledCipherSuites(strings);
+        }
+
+        public String[] getSupportedCipherSuites() {
+            return ss.getSupportedCipherSuites();
+        }
+
+        public String[] getSupportedProtocols() {
+            return ss.getSupportedProtocols();
+        }
+
+        public String[] getEnabledProtocols() {
+            return ss.getEnabledProtocols();
+        }
+
+        public void setEnabledProtocols(String[] strings) {
+            ss.setEnabledProtocols(strings);
+        }
+
+        public void setNeedClientAuth(boolean b) {
+            ss.setNeedClientAuth(b);
+        }
+
+        public boolean getNeedClientAuth() {
+            return ss.getNeedClientAuth();
+        }
+
+        public void setWantClientAuth(boolean b) {
+            ss.setWantClientAuth(b);
+        }
+
+        public boolean getWantClientAuth() {
+            return ss.getWantClientAuth();
+        }
+
+        public void setUseClientMode(boolean b) {
+            ss.setUseClientMode(b);
+        }
+
+        public boolean getUseClientMode() {
+            return ss.getUseClientMode();
+        }
+
+        public void setEnableSessionCreation(boolean b) {
+            ss.setEnableSessionCreation(b);
+        }
+
+        public boolean getEnableSessionCreation() {
+            return ss.getEnableSessionCreation();
+        }
+
+        public SSLParameters getSSLParameters() {
+            return ss.getSSLParameters();
+        }
+
+        public void setSSLParameters(SSLParameters sslParameters) {
+            ss.setSSLParameters(sslParameters);
         }
     }
 
+    private static Socket checkLocal(Socket socket) throws IOException {
+        InetAddress addr = socket.getInetAddress();
+        if (addr != null) {
+            if (addr.isLoopbackAddress()) {
+                return socket;
+            } else {
+                try {
+                    Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
+                    while (nis.hasMoreElements()) {
+                        NetworkInterface ni = nis.nextElement();
+                        Enumeration<InetAddress> ads = ni.getInetAddresses();
+                        while (ads.hasMoreElements()) {
+                            InetAddress ad = ads.nextElement();
+                            if (ad.equals(addr)) {
+                                return socket;
+                            }
+                        }
+                    }
+                } catch (SocketException e) {
+                    // Ignore
+                }
+            }
+        }
+        try {
+            socket.close();
+        } catch (Exception e) {
+            // Ignore
+        }
+        throw new IOException("Only connections from clients running on the host where the RMI remote objects have been exported are accepted.");
+    }
 
 }