mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

gbellato
19.50.2006 9cb56abfabba079462af7a8150371b427e67aa6d
add a test for JMX with SSL,
This test is currently disabled because it fails.

This test uses a keystore containing a self-signed certificate : tests/unit-tests-testng/resource/jmxkeystore
that is copied in the package at the TestCaseUtils.startServer time

This change also fix the warning in the JMX test
1 files added
2 files modified
189 ■■■■ changed files
opendj-sdk/opends/tests/unit-tests-testng/resource/jmxkeystore patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java 2 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/jmx/JmxConnectTest.java 187 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/resource/jmxkeystore
Binary files differ
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
@@ -149,6 +149,8 @@
                  new File(testConfigDir, "schema"));
    copyDirectory(new File(resourceDir, "MakeLDIF"),
                  new File(testConfigDir, "MakeLDIF"));
    copyFile(new File(testResourceDir, "jmxkeystore"),
             new File(testRoot, "jmxkeystore"));
    // Find some free ports for the listeners and write them to the
    // config-chamges.ldif file.
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/jmx/JmxConnectTest.java
@@ -26,8 +26,11 @@
 */
package org.opends.server.protocols.jmx;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -39,6 +42,8 @@
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.ConnectionHandler;
@@ -114,6 +119,58 @@
  }
  /**
   * Check that simple (no SSL) connections to the JMX service are
   * accepted when the given
   * credentials are OK and refused when the credentials are invalid.
   *
   */
  @Test(enabled=false)
  public void sslConnect() throws Exception
  {
    // configure the JMX ssl key manager
    ConfigEntry config = new ConfigEntry(TestCaseUtils.makeEntry(
        "dn: cn=Key Manager Provider,cn=JMX Connection Handler,cn=Connection Handlers,cn=config",
        "objectClass: top",
        "objectClass: ds-cfg-key-manager-provider",
        "objectClass: ds-cfg-file-based-key-manager-provider",
        "ds-cfg-key-manager-provider-class: org.opends.server.extensions.FileBasedKeyManagerProvider",
        "ds-cfg-key-manager-provider-enabled: true",
        "ds-cfg-key-store-file: " + getJmxKeystorePath(),
        "ds-cfg-key-store-type: JKS",
        "ds-cfg-key-store-pin: password"
         ), null);
    JmxConnectionHandler jmxConnectionHandler = getJmxConnectionHandler();
    assertNotNull(jmxConnectionHandler);
    StringBuilder reason = new StringBuilder();
    assertTrue(jmxConnectionHandler.configAddIsAcceptable(config, reason));
    ConfigChangeResult result =
      jmxConnectionHandler.applyConfigurationAdd(config);
    assertEquals(ResultCode.SUCCESS, result.getResultCode());
    // Enable SSL by setting ds-cfg-use-ssl boolean and the
    // certificate alias using ds-cfg-ssl-cert-nickname attribute.
    config = new ConfigEntry(TestCaseUtils.makeEntry(
        "dn: cn=JMX Connection Handler,cn=Connection Handlers,cn=config",
        "objectClass: top",
        "objectClass: ds-cfg-connection-handler",
        "objectClass: ds-cfg-jmx-connection-handler",
        "ds-cfg-ssl-cert-nickname: jmx-cert",
        "ds-cfg-connection-handler-class: org.opends.server.protocols.jmx.JmxConnectionHandler",
        "ds-cfg-connection-handler-enabled: true",
        "ds-cfg-use-ssl: true",
        "ds-cfg-listen-port: " + TestCaseUtils.getServerJmxPort(),
        "cn: JMX Connection Handler"
         ), null);
    configureJmx(config);
    MBeanServerConnection jmxc = sslConnect("cn=directory manager", "password",
                                            TestCaseUtils.getServerJmxPort());
    assertNotNull(jmxc);
  }
  /**
   * Build some data for the simpleGet test.
   */
  @DataProvider(name="simpleGet")
@@ -167,7 +224,7 @@
        TestCaseUtils.getServerJmxPort());
    assertNotNull(jmxc);
    
    Set<ObjectName> names = (Set<ObjectName>) jmxc.queryNames(null, null);
    Set names = jmxc.queryNames(null, null);
    names.clear();
    
    final String dn = "cn=config";
@@ -221,23 +278,11 @@
    MBeanServerConnection jmxc = connect("cn=directory manager", "password",
      TestCaseUtils.getServerJmxPort());
    assertNotNull(jmxc);
    // use JMX to get the current value of the JMX port number
    Long initJmxPort = (Long) jmxGet(dn, attribute, jmxc);
    assertNotNull(initJmxPort);
    
    // Get the Jmx connection handler from the core server
    List<ConnectionHandler> handlers = DirectoryServer.getConnectionHandlers();
    assertNotNull(handlers);
    JmxConnectionHandler jmxConnectionHandler = null;
    for (ConnectionHandler handler : handlers)
    {
      if (handler instanceof JmxConnectionHandler)
      {
         jmxConnectionHandler = (JmxConnectionHandler) handler;
        break;
      }
    }
    assertNotNull(jmxConnectionHandler);
    // change the configuration of the connection handler to use 
    // the current port + 1 as the new port number
    ConfigEntry config = new ConfigEntry(TestCaseUtils.makeEntry(
@@ -252,12 +297,7 @@
        "ds-cfg-listen-port: " + (initJmxPort+1),
        "cn: JMX Connection Handler"
         ), null);
    ArrayList<String> reasons = new ArrayList<String>();
    assertTrue(
        jmxConnectionHandler.hasAcceptableConfiguration(config, reasons));
    ConfigChangeResult configResult =
      jmxConnectionHandler.applyNewConfiguration(config, false);
    assertEquals(configResult.getResultCode(), ResultCode.SUCCESS);
    configureJmx(config);
    
    // connect the the JMX service using the new port
    jmxc = connect("cn=directory manager", "password", initJmxPort+1);
@@ -278,12 +318,45 @@
        "ds-cfg-listen-port: " + initJmxPort,
        "cn: JMX Connection Handler"
         ), null);
    assertTrue(
        jmxConnectionHandler.hasAcceptableConfiguration(config, reasons));
    configResult =
    configureJmx(config);
  }
  /**
   * @param config
   */
  private void configureJmx(ConfigEntry config)
  {
    ArrayList<String> reasons = new ArrayList<String>();
    // Get the Jmx connection handler from the core server
    JmxConnectionHandler jmxConnectionHandler = getJmxConnectionHandler();
    assertNotNull(jmxConnectionHandler);
    if (!jmxConnectionHandler.hasAcceptableConfiguration(config, reasons) )
      fail("unacceptable JMX configuration" + reasons);
    ConfigChangeResult configResult =
      jmxConnectionHandler.applyNewConfiguration(config, false);
    assertEquals(configResult.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Get a reference to the JMX connection handler.
   */
  private JmxConnectionHandler getJmxConnectionHandler()
  {
    List<ConnectionHandler> handlers = DirectoryServer.getConnectionHandlers();
    assertNotNull(handlers);
    JmxConnectionHandler jmxConnectionHandler = null;
    for (ConnectionHandler handler : handlers)
    {
      if (handler instanceof JmxConnectionHandler)
      {
         jmxConnectionHandler = (JmxConnectionHandler) handler;
        break;
      }
    }
    return jmxConnectionHandler;
  }
  
  
  /**
@@ -294,7 +367,7 @@
      throws MalformedURLException, IOException
  {
    HashMap<String, String[]> env = new HashMap<String, String[]>();
    // Provide the credentials required by the server to successfully
    // perform user authentication
    //
@@ -306,11 +379,60 @@
    else
      credentials = new String[] { user , password };
    env.put("jmx.remote.credentials", credentials);
    // Create an RMI connector client and
    // connect it to the RMI connector server
    //
    JMXServiceURL url = new JMXServiceURL(
      "service:jmx:rmi:///jndi/rmi://localhost:"+ jmxPort +
          "/org.opends.server.protocols.jmx.client-unknown");
    JMXConnector jmxc = null;
    try
    {
      jmxc = JMXConnectorFactory.connect(url, env);
      return jmxc.getMBeanServerConnection();
    } catch (SecurityException e)
    {
      return null;
    }
  }
  /**
   * Connect to the JMX service using SSL.
   */
  private MBeanServerConnection
      sslConnect(String user, String password, long jmxPort)
      throws Exception
  {
    HashMap<String, Object> env = new HashMap<String, Object>();
    // Provide the credentials required by the server to successfully
    // perform user authentication
    String[] credentials;
    if ((user == null) && (password == null))
    {
      credentials = null;
    }
    else
      credentials = new String[] { user , password };
    env.put("jmx.remote.credentials", credentials);
    // Provide the Trust manager.
    KeyStore ks = null ;
    ks = KeyStore.getInstance("JKS");
    FileInputStream keyStoreFile = new FileInputStream(getJmxKeystorePath());
    ks.load(keyStoreFile, "password".toCharArray());
    TrustManagerFactory tmf =
      TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    TrustManager tms[] = tmf.getTrustManagers();
    env.put(JmxConnectionHandler.TRUST_MANAGER_ARRAY_KEY, tms);
    // Create an RMI connector client and
    // connect it to the RMI connector server
    JMXServiceURL url = new JMXServiceURL(
      "service:jmx:rmi:///jndi/rmi://localhost:"+ jmxPort +
          "/org.opends.server.protocols.jmx.client-unknown");
@@ -328,6 +450,15 @@
  }
  /**
   * @return
   */
  private String getJmxKeystorePath()
  {
    return DirectoryServer.getServerRoot() + File.separator
                        + "jmxkeystore";
  }
  /**
   * disable the JMX front-end thorugh JMX operation.
  private void disableJmx(JMXConnector jmxc)
@@ -353,7 +484,7 @@
  */
  /**
   * Get an attrbiue value through JMX.
   * Get an attribute value through JMX.
   */
  private Object jmxGet(String dn, String attributeName,
                        MBeanServerConnection mbsc)
@@ -369,7 +500,7 @@
  }
  /**
   * Set an attrbiue value through JMX.
   * Set an attribute value through JMX.
   */
  private void jmxSet(String dn, String attributeName,
                      Object value, MBeanServerConnection mbsc)