summaryrefslogtreecommitdiff
path: root/qpid/java/management
diff options
context:
space:
mode:
authorAidan Skinner <aidan@apache.org>2009-02-13 14:00:10 +0000
committerAidan Skinner <aidan@apache.org>2009-02-13 14:00:10 +0000
commit448e6bff629c2d8d9b3cbd7c39d8eefd2b33c06e (patch)
treedf337797ff6438c5b09f208604fd4d54951ee312 /qpid/java/management
parentbc5378a4b3220ec8c1e700c5fe705d983b4b0c7b (diff)
downloadqpid-python-448e6bff629c2d8d9b3cbd7c39d8eefd2b33c06e.tar.gz
QPID-1511 : Adds authentication and ssl encryption capabilities to the RMI based JMXConnectorServer in use, enforces use of the custom MBeanInvocationhandlerImp when using the RMI based JMX, and implements a customised RMI registry to prevent external changes being possible. Updated Management console accordingly.
Patch from Robbert Gemmell <gemmellr@dcs.gla.ac.uk> git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@744113 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/management')
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java56
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java63
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini12
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini11
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini11
5 files changed, 134 insertions, 19 deletions
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java
index c9955329d0..f5831c9e28 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java
@@ -29,6 +29,7 @@ import java.util.Map;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
+import javax.net.ssl.SSLException;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslClientFactory;
@@ -40,8 +41,13 @@ import org.apache.qpid.management.common.sasl.UserPasswordCallbackHandler;
import org.apache.qpid.management.common.sasl.UsernameHashedPasswordCallbackHandler;
public class JMXConnnectionFactory {
-
- public static JMXConnector getJMXConnection(long timeout, String host, int port, String username, String password) throws Exception
+
+ private static final String NON_JRMP_SERVER = "non-JRMP server at remote endpoint";
+ private static final String SERVER_SUPPORTED_PROFILES = "The server supported profiles";
+ private static final String CLIENT_REQUIRED_PROFILES = "do not match the client required profiles";
+
+ public static JMXConnector getJMXConnection(long timeout, String host, int port, String username, String password)
+ throws SSLException, IOException, Exception
{
//auto-negotiate an RMI or JMXMP (SASL/CRAM-MD5 or SASL/PLAIN) JMX connection to broker
try
@@ -51,11 +57,30 @@ public class JMXConnnectionFactory {
catch (IOException rmiIOE)
{
// check if the ioe was raised because we tried connecting to a non RMI-JRMP based JMX server
- boolean jrmpServer = !rmiIOE.getMessage().contains("non-JRMP server at remote endpoint");
+ boolean jrmpServer = !rmiIOE.getMessage().contains(NON_JRMP_SERVER);
if (jrmpServer)
{
- throw rmiIOE;
+ //it was an RMI-JRMP based JMX server, so something else went wrong. Check for SSL issues.
+ Throwable rmiIOECause = rmiIOE.getCause();
+ boolean isSSLException = false;
+ if (rmiIOECause != null)
+ {
+ isSSLException = rmiIOECause instanceof SSLException;
+ }
+
+ //if it was an SSLException based cause, throw it
+ if (isSSLException)
+ {
+ throw (SSLException) rmiIOECause;
+ }
+ else
+ {
+ //can't determine cause, throw new IOE citing the original as cause
+ IOException nioe = new IOException();
+ nioe.initCause(rmiIOE);
+ throw nioe;
+ }
}
else
{
@@ -67,8 +92,8 @@ public class JMXConnnectionFactory {
catch (IOException cramIOE)
{
// check if the IOE was raised because we tried connecting to a SASL/PLAIN server using SASL/CRAM-MD5
- boolean plainProfileServer = cramIOE.getMessage().contains("The server supported profiles [SASL/PLAIN]" +
- " do not match the client required profiles [SASL/CRAM-MD5]");
+ boolean plainProfileServer = cramIOE.getMessage().contains(SERVER_SUPPORTED_PROFILES +
+ " [" + Constants.SASL_PLAIN + "] " + CLIENT_REQUIRED_PROFILES + " [" + Constants.SASL_CRAMMD5 + "]");
if (!plainProfileServer)
{
@@ -87,7 +112,7 @@ public class JMXConnnectionFactory {
{
/* Out of options now. Check that the IOE was raised because we tried connecting to a server
* which didnt support SASL/PLAIN. If so, signal an unknown profile type. If not, raise the exception. */
- boolean unknownProfile = cramIOE.getMessage().contains("do not match the client required profiles [SASL/PLAIN]");
+ boolean unknownProfile = plainIOE.getMessage().contains(CLIENT_REQUIRED_PROFILES + " [" + Constants.SASL_PLAIN + "]");
if (unknownProfile)
{
@@ -106,18 +131,19 @@ public class JMXConnnectionFactory {
}
}
- private static JMXConnector createJMXconnector(String connectionType, long timeout, String host, int port, String userName, String password) throws IOException, Exception
+ private static JMXConnector createJMXconnector(String connectionType, long timeout, String host, int port,
+ String userName, String password) throws IOException, Exception
{
Map<String, Object> env = new HashMap<String, Object>();
- String securityMechanism = null;
JMXServiceURL jmxUrl = null;
if (connectionType == "RMI")
{
- securityMechanism = Constants.MECH_PLAIN;
-
jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
- env = null;
+
+ //Add user credential's to environment map for RMIConnector startup.
+ //These will be used for authentication by the remote RMIConnectorServer if supported, or ignored otherwise.
+ env.put(JMXConnector.CREDENTIALS, new String[] {userName,password});
}
else if (connectionType.contains("JMXMP"))
{
@@ -143,8 +169,6 @@ public class JMXConnnectionFactory {
if (connectionType == "JMXMP_CRAM-MD5")
{
- securityMechanism = Constants.MECH_CRAMMD5;
-
Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>();
map.put("CRAM-MD5-HASHED", CRAMMD5HashedSaslClientFactory.class);
Security.addProvider(new JCAProvider(map));
@@ -156,8 +180,6 @@ public class JMXConnnectionFactory {
}
else if (connectionType == "JMXMP_PLAIN")
{
- securityMechanism = Constants.MECH_PLAIN;
-
Security.addProvider(new SaslProvider());
CallbackHandler handler = new UserPasswordCallbackHandler(userName, password);
env.put("jmx.remote.profiles", Constants.SASL_PLAIN);
@@ -165,7 +187,7 @@ public class JMXConnnectionFactory {
}
else
{
- throw new Exception("Unknown authentication mechanism");
+ throw new Exception("Unknown JMXMP authentication mechanism");
}
}
else
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
index 202c6ea650..474e31cd8f 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
@@ -24,6 +24,11 @@ import static org.apache.qpid.management.ui.Constants.ERROR_SERVER_CONNECTION;
import java.io.IOException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLKeyException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
import org.apache.qpid.management.ui.Constants;
@@ -47,6 +52,10 @@ public class AbstractAction
public static final String SERVER_UNAVAILABLE = "Unable to connect to the specified Qpid JMX server";
public static final String INVALID_PERSPECTIVE = "Invalid Perspective";
public static final String CHANGE_PERSPECTIVE = "Please use the Qpid Management Perspective";
+
+ private static final String SSL_EMPTY_TRUSTANCHORS = "the trustAnchors parameter must be non-empty";
+ private static final String SSL_UNABLE_TO_FIND_CERTPATH = "sun.security.provider.certpath.SunCertPathBuilderException: " +
+ "unable to find valid certification path to requested target";
/**
* We will cache window object in order to
@@ -93,9 +102,59 @@ public class AbstractAction
//determine the error message to display
if (msg == null)
{
- if (ex instanceof IOException)
+ if (ex instanceof SSLException)
+ {
+ if (ex instanceof SSLKeyException)
+ {
+ msg = "SSL key was invalid, please check the certificate configuration.";
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else if (ex instanceof SSLPeerUnverifiedException)
+ {
+ msg = "SSL peer identity could not be verified, please ensure valid certificate configuration.";
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else if (ex instanceof SSLHandshakeException)
+ {
+ if (ex.getMessage().contains(SSL_UNABLE_TO_FIND_CERTPATH))
+ {
+ msg = "Unable to certify the provided SSL certificate using the current SSL trust store.";
+ }
+ else
+ {
+ //cause unknown, provide a trace too
+ MBeanUtility.printStackTrace(ex);
+ msg = "SSL handhshake error.";
+ }
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else
+ {
+ //general SSL Exception.
+ if (ex.getMessage().contains(SSL_EMPTY_TRUSTANCHORS))
+ {
+ msg = "Unable to locate the specified SSL certificate trust store, please check the configuration.";
+ }
+ else
+ {
+ //cause unknown, print stack trace
+ MBeanUtility.printStackTrace(ex);
+ msg = "SSL connection error.";
+ }
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ }
+ else if (ex instanceof IOException)
{
- //IOException, eg when trying to connect to a server/port with no JMX server running
+ //uncaught IOException, eg when trying to connect to a server/port with no JMX server running
msg = SERVER_UNAVAILABLE;
//Display error dialogue and return
displayErrorDialogue(msg, title);
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini
index 8fd70ba19f..19ceb6f717 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini
@@ -23,3 +23,15 @@
-XX:MaxPermSize=256m
-Dosgi.requiredJavaVersion=1.5
-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini
index 231adf2d8b..2a31b9b2c7 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini
@@ -29,3 +29,14 @@
-Dosgi.requiredJavaVersion=1.5
-Declipse.consoleLog=true
-Dorg.eclipse.swt.internal.carbon.smallFonts
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini
index 9f3ad202ad..9e3de042d5 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini
@@ -23,3 +23,14 @@
-XX:MaxPermSize=256m
-Dosgi.requiredJavaVersion=1.5
-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+