You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2018/05/21 20:03:48 UTC

[geode] branch develop updated: GEODE-5230: Pulse does not work when SSL is enabled for JMX (#1976)

This is an automated email from the ASF dual-hosted git repository.

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 75e8b9e  GEODE-5230: Pulse does not work when SSL is enabled for JMX (#1976)
75e8b9e is described below

commit 75e8b9e4fe8006982f7bfee1e5702af41c6c341e
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Mon May 21 13:03:43 2018 -0700

    GEODE-5230: Pulse does not work when SSL is enabled for JMX (#1976)
---
 .../tools/pulse/PulseSecurityWithSSLTest.java      |  2 +-
 .../geode/management/internal/JettyHelper.java     | 15 +++++--
 .../geode/management/internal/ManagementAgent.java | 47 +++++++++++++++++++---
 .../geode/management/internal/RestAgent.java       |  6 +--
 .../tools/pulse/internal/PulseAppListener.java     |  8 +++-
 .../tools/pulse/internal/data/JMXDataUpdater.java  | 26 ++++++++----
 .../tools/pulse/internal/data/Repository.java      |  9 +++++
 .../tools/pulse/internal/PulseAppListenerTest.java | 14 ++++++-
 .../geode/tools/pulse/tests/rules/ServerRule.java  |  2 +-
 9 files changed, 105 insertions(+), 24 deletions(-)

diff --git a/geode-assembly/src/test/java/org/apache/geode/tools/pulse/PulseSecurityWithSSLTest.java b/geode-assembly/src/test/java/org/apache/geode/tools/pulse/PulseSecurityWithSSLTest.java
index 8d97150..be51336 100644
--- a/geode-assembly/src/test/java/org/apache/geode/tools/pulse/PulseSecurityWithSSLTest.java
+++ b/geode-assembly/src/test/java/org/apache/geode/tools/pulse/PulseSecurityWithSSLTest.java
@@ -56,7 +56,7 @@ public class PulseSecurityWithSSLTest {
   @BeforeClass
   public static void beforeClass() throws Exception {
     Properties securityProps = new Properties();
-    securityProps.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannels.WEB);
+    securityProps.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannels.ALL);
     securityProps.setProperty(SSL_KEYSTORE, jks.getCanonicalPath());
     securityProps.setProperty(SSL_KEYSTORE_PASSWORD, "password");
     securityProps.setProperty(SSL_TRUSTSTORE, jks.getCanonicalPath());
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java b/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
index bbf6847..257cd2c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
@@ -15,6 +15,7 @@
 package org.apache.geode.management.internal;
 
 import java.io.File;
+import java.util.Properties;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.commons.lang.StringUtils;
@@ -46,7 +47,6 @@ public class JettyHelper {
 
   private static final String FILE_PATH_SEPARATOR = System.getProperty("file.separator");
   private static final String USER_DIR = System.getProperty("user.dir");
-
   private static final String USER_NAME = System.getProperty("user.name");
 
   private static final String HTTPS = "https";
@@ -58,6 +58,8 @@ public class JettyHelper {
   public static final String SECURITY_SERVICE_SERVLET_CONTEXT_PARAM =
       "org.apache.geode.securityService";
 
+  private static final String GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM = "org.apache.geode.sslConfig";
+
   public static Server initJetty(final String bindAddress, final int port, SSLConfig sslConfig) {
 
     final Server jettyServer = new Server();
@@ -117,6 +119,10 @@ public class JettyHelper {
         sslContextFactory.setTrustStorePassword(sslConfig.getTruststorePassword());
       }
 
+      if (StringUtils.isNotBlank(sslConfig.getTruststoreType())) {
+        sslContextFactory.setTrustStoreType(sslConfig.getTruststoreType());
+      }
+
       if (logger.isDebugEnabled()) {
         logger.debug(sslContextFactory.dump());
       }
@@ -159,7 +165,7 @@ public class JettyHelper {
   }
 
   public static Server addWebApplication(final Server jetty, final String webAppContext,
-      final String warFilePath, SecurityService securityService) {
+      final String warFilePath, SecurityService securityService, Properties sslConfig) {
     WebAppContext webapp = new WebAppContext();
     webapp.setContextPath(webAppContext);
     webapp.setWar(warFilePath);
@@ -167,6 +173,10 @@ public class JettyHelper {
     webapp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
     webapp.setAttribute(SECURITY_SERVICE_SERVLET_CONTEXT_PARAM, securityService);
 
+    // This is only required for Pulse because in embedded mode, with SSL enabled, Pulse needs to
+    // know how to make SSL RMI connections.
+    webapp.setAttribute(GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM, sslConfig);
+
     File tmpPath = new File(getWebAppBaseDirectory(webAppContext));
     tmpPath.mkdirs();
     webapp.setTempDirectory(tmpPath);
@@ -176,7 +186,6 @@ public class JettyHelper {
     return jetty;
   }
 
-
   private static String getWebAppBaseDirectory(final String context) {
     String underscoredContext = context.replace("/", "_");
     final String workingDirectory = USER_DIR.concat(FILE_PATH_SEPARATOR)
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
index 4532652..8d4c928 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
@@ -27,6 +27,7 @@ import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.rmi.server.UnicastRemoteObject;
 import java.util.HashMap;
+import java.util.Properties;
 import java.util.Set;
 
 import javax.management.InstanceAlreadyExistsException;
@@ -249,22 +250,22 @@ public class ManagementAgent {
 
           if (agentUtil.isWebApplicationAvailable(gemfireWar)) {
             this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire", gemfireWar,
-                securityService);
+                securityService, null);
             this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode-mgmt",
-                gemfireWar, securityService);
+                gemfireWar, securityService, null);
           }
 
           if (agentUtil.isWebApplicationAvailable(pulseWar)) {
-            this.httpServer =
-                JettyHelper.addWebApplication(this.httpServer, "/pulse", pulseWar, securityService);
+            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/pulse", pulseWar,
+                securityService, createSslProps());
           }
 
           if (isServer && this.config.getStartDevRestApi()) {
             if (agentUtil.isWebApplicationAvailable(gemfireAPIWar)) {
               this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode",
-                  gemfireAPIWar, securityService);
+                  gemfireAPIWar, securityService, null);
               this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire-api",
-                  gemfireAPIWar, securityService);
+                  gemfireAPIWar, securityService, null);
               isRestWebAppAdded = true;
             }
           } else {
@@ -328,6 +329,40 @@ public class ManagementAgent {
     }
   }
 
+  private Properties createSslProps() {
+    Properties sslProps = new Properties();
+    if (StringUtils.isNotEmpty(config.getSSLKeyStore())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_KEYSTORE, config.getSSLKeyStore());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLKeyStorePassword())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_KEYSTORE_PASSWORD,
+          config.getSSLKeyStorePassword());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLKeyStoreType())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_KEYSTORE_TYPE, config.getSSLKeyStoreType());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLTrustStore())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_TRUSTSTORE, config.getSSLTrustStore());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLTrustStorePassword())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_TRUSTSTORE_PASSWORD,
+          config.getSSLTrustStorePassword());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLTrustStoreType())) {
+      sslProps.put(SSLConfigurationFactory.JAVAX_TRUSTSTORE_TYPE, config.getSSLTrustStoreType());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLCiphers())
+        && !config.getSSLCiphers().equalsIgnoreCase("any")) {
+      sslProps.put("javax.rmi.ssl.client.enabledCipherSuites", config.getSSLCiphers());
+    }
+    if (StringUtils.isNotEmpty(config.getSSLProtocols())
+        && !config.getSSLProtocols().equalsIgnoreCase("any")) {
+      sslProps.put("javax.rmi.ssl.client.enabledProtocols", config.getSSLProtocols());
+    }
+
+    return sslProps;
+  }
+
   private String getHost(final String bindAddress) throws UnknownHostException {
     if (StringUtils.isNotBlank(this.config.getJmxManagerHostnameForClients())) {
       return this.config.getJmxManagerHostnameForClients();
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
index dccf883..ddac934 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
@@ -138,9 +138,9 @@ public class RestAgent {
             SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.WEB));
 
         this.httpServer = JettyHelper.addWebApplication(httpServer, "/gemfire-api", gemfireAPIWar,
-            securityService);
-        this.httpServer =
-            JettyHelper.addWebApplication(httpServer, "/geode", gemfireAPIWar, securityService);
+            securityService, null);
+        this.httpServer = JettyHelper.addWebApplication(httpServer, "/geode", gemfireAPIWar,
+            securityService, null);
 
         if (logger.isDebugEnabled()) {
           logger.debug("Starting HTTP embedded server on port ({}) at bind-address ({})...",
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseAppListener.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseAppListener.java
index e55a4f6..908db57 100644
--- a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseAppListener.java
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseAppListener.java
@@ -45,6 +45,7 @@ import org.apache.geode.tools.pulse.internal.data.Repository;
 public class PulseAppListener implements ServletContextListener {
   private static final Logger logger = LogManager.getLogger();
   private final ResourceBundle resourceBundle = Repository.get().getResourceBundle();
+  private static final String GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM = "org.apache.geode.sslConfig";
 
   private Properties pulseProperties;
   private Properties pulseSecurityProperties;
@@ -88,11 +89,16 @@ public class PulseAppListener implements ServletContextListener {
       repository.setPort(System.getProperty(PulseConstants.SYSTEM_PROPERTY_PULSE_PORT,
           PulseConstants.GEMFIRE_DEFAULT_PORT));
 
-      // SSL, all the other system properties are already set in the embedded VM
       repository.setUseSSLManager(
           Boolean.valueOf(System.getProperty(PulseConstants.SYSTEM_PROPERTY_PULSE_USESSL_MANAGER)));
       repository.setUseSSLLocator(
           Boolean.valueOf(System.getProperty(PulseConstants.SYSTEM_PROPERTY_PULSE_USESSL_LOCATOR)));
+
+      Object sslProperties =
+          event.getServletContext().getAttribute(GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM);
+      if (sslProperties instanceof Properties) {
+        repository.setJavaSslProperties((Properties) sslProperties);
+      }
     } else {
       // jmx connection parameters
       logger.info(resourceBundle.getString("LOG_MSG_APP_RUNNING_NONEMBEDDED_MODE"));
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/JMXDataUpdater.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/JMXDataUpdater.java
index 1dac541..fa5d9d5 100644
--- a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/JMXDataUpdater.java
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/JMXDataUpdater.java
@@ -34,6 +34,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Properties;
 import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -209,14 +210,25 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
         Map<String, Object> env = new HashMap<String, Object>();
         env.put(JMXConnector.CREDENTIALS, creds);
 
-        if (repository.isUseSSLManager()) {
-          // use ssl to connect
-          env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
+        Properties originalProperties = System.getProperties();
+        try {
+          Properties updatedProperties = new Properties(originalProperties);
+          if (repository.isUseSSLManager()) {
+            for (String sslProperty : repository.getJavaSslProperties().stringPropertyNames()) {
+              updatedProperties.setProperty(sslProperty,
+                  repository.getJavaSslProperties().getProperty(sslProperty));
+            }
+
+            System.setProperties(updatedProperties);
+            env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
+          }
+          logger.info("Connecting to jmxURL : {}", jmxSerURL);
+          this.conn = JMXConnectorFactory.connect(url, env);
+          this.mbs = this.conn.getMBeanServerConnection();
+          cluster.setConnectedFlag(true);
+        } finally {
+          System.setProperties(originalProperties);
         }
-        logger.info("Connecting to jmxURL : {}", jmxSerURL);
-        this.conn = JMXConnectorFactory.connect(url, env);
-        this.mbs = this.conn.getMBeanServerConnection();
-        cluster.setConnectedFlag(true);
       }
     } catch (Exception e) {
       cluster.setConnectedFlag(false);
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/Repository.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/Repository.java
index b6f467e..5ab58b4 100644
--- a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/Repository.java
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/data/Repository.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Properties;
 import java.util.ResourceBundle;
 
 import org.apache.logging.log4j.LogManager;
@@ -43,6 +44,7 @@ public class Repository {
   private String port;
   private boolean useSSLLocator = false;
   private boolean useSSLManager = false;
+  private Properties javaSslProperties;
 
   Locale locale =
       new Locale(PulseConstants.APPLICATION_LANGUAGE, PulseConstants.APPLICATION_COUNTRY);
@@ -104,6 +106,13 @@ public class Repository {
     return this.pulseConfig;
   }
 
+  public Properties getJavaSslProperties() {
+    return javaSslProperties;
+  }
+
+  public void setJavaSslProperties(Properties javaSslProperties) {
+    this.javaSslProperties = javaSslProperties;
+  }
 
   /**
    * this will return a cluster already connected to the geode jmx manager for the user in the
diff --git a/geode-pulse/src/test/java/org/apache/geode/tools/pulse/internal/PulseAppListenerTest.java b/geode-pulse/src/test/java/org/apache/geode/tools/pulse/internal/PulseAppListenerTest.java
index 7454b0c..80b07b8 100644
--- a/geode-pulse/src/test/java/org/apache/geode/tools/pulse/internal/PulseAppListenerTest.java
+++ b/geode-pulse/src/test/java/org/apache/geode/tools/pulse/internal/PulseAppListenerTest.java
@@ -16,8 +16,11 @@
 
 package org.apache.geode.tools.pulse.internal;
 
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 
 import org.junit.After;
@@ -41,16 +44,23 @@ public class PulseAppListenerTest {
   @Rule
   public final TestRule restoreSystemProperties = new RestoreSystemProperties();
 
+  ServletContextEvent contextEvent;
+
   @Before
   public void setUp() {
     repository = Repository.get();
     appListener = new PulseAppListener();
+
+    contextEvent = mock(ServletContextEvent.class);
+    ServletContext context = mock(ServletContext.class);
+    when(context.getAttribute(anyString())).thenReturn(null);
+    when(contextEvent.getServletContext()).thenReturn(context);
   }
 
   @Test
   public void embeddedModeDefaultPropertiesRepositoryInitializationTest() {
     System.setProperty(PulseConstants.SYSTEM_PROPERTY_PULSE_EMBEDDED, "true");
-    appListener.contextInitialized(mock(ServletContextEvent.class));
+    appListener.contextInitialized(contextEvent);
 
     Assert.assertEquals(false, repository.getJmxUseLocator());
     Assert.assertEquals(false, repository.isUseSSLManager());
@@ -70,7 +80,7 @@ public class PulseAppListenerTest {
     System.setProperty(PulseConstants.SYSTEM_PROPERTY_PULSE_USESSL_LOCATOR,
         Boolean.TRUE.toString());
 
-    appListener.contextInitialized(mock(ServletContextEvent.class));
+    appListener.contextInitialized(contextEvent);
 
     Assert.assertEquals(false, repository.getJmxUseLocator());
     Assert.assertEquals(true, repository.isUseSSLManager());
diff --git a/geode-pulse/src/test/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java b/geode-pulse/src/test/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
index 6164ed6..4ccfe25 100644
--- a/geode-pulse/src/test/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
+++ b/geode-pulse/src/test/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
@@ -47,7 +47,7 @@ public class ServerRule extends ExternalResource {
 
     int httpPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     jetty = JettyHelper.initJetty(LOCALHOST, httpPort, new SSLConfig());
-    JettyHelper.addWebApplication(jetty, PULSE_CONTEXT, getPulseWarPath(), null);
+    JettyHelper.addWebApplication(jetty, PULSE_CONTEXT, getPulseWarPath(), null, null);
     pulseURL = "http://" + LOCALHOST + ":" + httpPort + PULSE_CONTEXT;
     System.out.println("Pulse started at " + pulseURL);
   }

-- 
To stop receiving notification emails like this one, please contact
jensdeppe@apache.org.