summaryrefslogtreecommitdiff
path: root/java/management/eclipse-plugin/src
diff options
context:
space:
mode:
authorBhupendra Bhusman Bhardwaj <bhupendrab@apache.org>2007-04-11 14:16:02 +0000
committerBhupendra Bhusman Bhardwaj <bhupendrab@apache.org>2007-04-11 14:16:02 +0000
commit41a95c994d425ea0dcb1ae5a099da1e530eadc87 (patch)
treef2d54f1ad81df7e5b79269129c2e66588f2a8418 /java/management/eclipse-plugin/src
parentb287b96e81dfff14c63285afb8c461187b18f87f (diff)
downloadqpid-python-41a95c994d425ea0dcb1ae5a099da1e530eadc87.tar.gz
QPID-444 : added CRAM-MD5-HASHED mechanism for sasl
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2@527499 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/management/eclipse-plugin/src')
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java10
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java5
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java5
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java56
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java20
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java60
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java56
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java108
8 files changed, 283 insertions, 37 deletions
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
index c15bdc4fa0..714f84ea49 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -41,8 +41,9 @@ public abstract class ApplicationRegistry
{
private static ImageRegistry imageRegistry = new ImageRegistry();
private static FontRegistry fontRegistry = new FontRegistry();
- public static final boolean enableSecurity = Boolean.getBoolean("security");
-
+ public static final boolean debug = Boolean.getBoolean("debug");
+ public static final String securityMechanism = System.getProperty("security", null);
+
static
{
imageRegistry.put(Constants.CONSOLE_IMAGE,
@@ -131,4 +132,9 @@ public abstract class ApplicationRegistry
_closedServerList.clear();
return list;
}
+
+ public static String getSecurityMechanism()
+ {
+ return securityMechanism;
+ }
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
index 91dec841cf..dd3c388ed4 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
@@ -123,4 +123,9 @@ public class Constants
public final static String INFO_HOST_PORT = "Please enter the port number";
public final static String INFO_USERNAME = "Please enter the " + USERNAME;
public final static String INFO_PASSWORD = "Please enter the " + PASSWORD;
+
+ public final static String MECH_CRAMMD5 = "CRAM-MD5";
+ public final static String MECH_PLAIN = "PLAIN";
+ public final static String SASL_CRAMMD5 = "SASL/CRAM-MD5";
+ public final static String SASL_PLAIN = "SASL/PLAIN";
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
index 82447d645e..2be0ddbebf 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
@@ -45,10 +45,7 @@ public class ClientListener implements NotificationListener
{
ObjectName objName = null;
String type = notification.getType();
- if (MBeanUtility.isDebug())
- {
- System.out.println(type + ":" + objName);
- }
+ MBeanUtility.printOutput(type + ":" + objName);
if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
{
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
index 435f7f2ff1..4040f544d1 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.management.ui.jmx;
+import static org.apache.qpid.management.ui.Constants.*;
+
import java.lang.reflect.Constructor;
import java.security.Security;
import java.util.ArrayList;
@@ -37,9 +39,9 @@ import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
+import javax.security.sasl.SaslClientFactory;
import org.apache.qpid.management.ui.ApplicationRegistry;
-import org.apache.qpid.management.ui.Constants;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
import org.apache.qpid.management.ui.ServerRegistry;
@@ -47,8 +49,10 @@ import org.apache.qpid.management.ui.model.ManagedAttributeModel;
import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.NotificationObject;
import org.apache.qpid.management.ui.model.OperationDataModel;
+import org.apache.qpid.management.ui.sasl.JCAProvider;
import org.apache.qpid.management.ui.sasl.SaslProvider;
import org.apache.qpid.management.ui.sasl.UserPasswordCallbackHandler;
+import org.apache.qpid.management.ui.sasl.UsernameHashedPasswordCallbackHandler;
public class JMXServerRegistry extends ServerRegistry
@@ -89,37 +93,58 @@ public class JMXServerRegistry extends ServerRegistry
super(server);
JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl());
Map<String, Object> env = null;
+ String securityMechanism = ApplicationRegistry.getSecurityMechanism();
- if (ApplicationRegistry.enableSecurity)
+ if (securityMechanism != null)
{
try
{
// Check if the JMXMP connector is available
Class klass = Class.forName("javax.management.remote.jmxmp.JMXMPConnector");
- // Now create the instance of JMXMPConnector
- Security.addProvider(new SaslProvider());
jmxUrl = new JMXServiceURL("jmxmp", server.getHost(), server.getPort());
-
env = new HashMap<String, Object>();
- env.put("jmx.remote.profiles", "SASL/PLAIN");
- //env.put("jmx.remote.profiles", "SASL/CRAM-MD5");
- env.put("jmx.remote.sasl.callback.handler",
- new UserPasswordCallbackHandler(server.getUser(), server.getPassword()));
+ if (MECH_CRAMMD5.equals(securityMechanism))
+ {
+ // For SASL/CRAM-MD5
+ Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>();
+ Class<?> clazz = Class.forName("org.apache.qpid.management.ui.sasl.CRAMMD5HashedSaslClientFactory");
+ map.put("CRAM-MD5-HASHED", (Class<? extends SaslClientFactory>) clazz);
+
+ Security.addProvider(new JCAProvider(map));
+ env.put("jmx.remote.profiles", SASL_CRAMMD5);
+ env.put("jmx.remote.sasl.callback.handler",
+ new UsernameHashedPasswordCallbackHandler(server.getUser(), server.getPassword()));
+ }
+ else if (MECH_PLAIN.equals(securityMechanism))
+ {
+ // For SASL/PLAIN
+ Security.addProvider(new SaslProvider());
+ env.put("jmx.remote.profiles", SASL_PLAIN);
+ env.put("jmx.remote.sasl.callback.handler",
+ new UserPasswordCallbackHandler(server.getUser(), server.getPassword()));
+ }
+ else
+ {
+ MBeanUtility.printOutput("Security mechanism " + securityMechanism + " is not supported.");
+ }
+
+ // Now create the instance of JMXMPConnector
Class[] paramTypes = {JMXServiceURL.class, Map.class};
Constructor cons = klass.getConstructor(paramTypes);
Object[] args = {jmxUrl, env};
Object theObject = cons.newInstance(args);
+
_jmxc = (JMXConnector)theObject;
_jmxc.connect();
- System.out.println("Starting JMXConnector with SASL. Server=" + server.getName());
+ MBeanUtility.printOutput("Starting JMXConnector with SASL. Server=" + server.getName());
}
catch (Exception ex)
{
// When JMXMPConnector is not available
- System.out.println("Starting JMXConnector. Server=" + server.getName());
+ MBeanUtility.printOutput("Starting JMXConnector. Server=" + server.getName());
jmxUrl = new JMXServiceURL(server.getUrl());
_jmxc = JMXConnectorFactory.connect(jmxUrl, null);
}
@@ -197,10 +222,7 @@ public class JMXServerRegistry extends ServerRegistry
public void removeManagedObject(ManagedBean mbean)
{
- if (MBeanUtility.isDebug())
- {
- System.out.println("Removing MBean:" + mbean.getUniqueName());
- }
+ MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName());
if (mbean.isQueue())
{
@@ -296,7 +318,7 @@ public class JMXServerRegistry extends ServerRegistry
map.put(name, list);
}
// Now add the notification type to the list
- if (Constants.ALL.equals(type))
+ if (ALL.equals(type))
{
List<NotificationInfoModel> infoList = _notificationInfoMap.get(mbean.getUniqueName());
for (NotificationInfoModel model : infoList)
@@ -355,7 +377,7 @@ public class JMXServerRegistry extends ServerRegistry
HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName());
if (map.containsKey(name))
{
- if (Constants.ALL.equals(type))
+ if (ALL.equals(type))
{
map.remove(name);
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
index 6c34ec9898..41db11c10e 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
@@ -60,13 +60,6 @@ import org.apache.qpid.management.ui.views.ViewUtility;
*/
public class MBeanUtility
{
- private static boolean _debug;
- static
- {
- String debug = System.getProperty("debug");
- _debug = "true".equalsIgnoreCase(debug) ? true : false;
- }
-
public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
/**
@@ -461,18 +454,17 @@ public class MBeanUtility
return Arrays.asList(domains);
}
- /**
- * return true if System property is set to true -Ddebug=true
- * @return
- */
- public static boolean isDebug()
+ public static void printOutput(String statement)
{
- return _debug;
+ if (ApplicationRegistry.debug)
+ {
+ System.out.println(statement);
+ }
}
private static void printStackTrace(Throwable ex)
{
- if (isDebug())
+ if (ApplicationRegistry.debug)
{
ex.printStackTrace();
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
new file mode 100644
index 0000000000..32a0c12344
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.qpid.management.ui.sasl;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslException;
+
+public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory
+{
+ /** The name of this mechanism */
+ public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+ public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol,
+ String serverName, Map<String, ?> props, CallbackHandler cbh)
+ throws SaslException
+ {
+ for (int i = 0; i < mechanisms.length; i++)
+ {
+ if (mechanisms[i].equals(MECHANISM))
+ {
+ if (cbh == null)
+ {
+ throw new SaslException("CallbackHandler must not be null");
+ }
+
+ String[] mechs = {"CRAM-MD5"};
+ return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh);
+ }
+ }
+ return null;
+ }
+
+ public String[] getMechanismNames(Map props)
+ {
+ return new String[]{MECHANISM};
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java
new file mode 100644
index 0000000000..d8189f3ac3
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.qpid.management.ui.sasl;
+
+import java.security.Provider;
+import java.util.Map;
+
+import javax.security.sasl.SaslClientFactory;
+
+public class JCAProvider extends Provider
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates the security provider with a map from SASL mechanisms to implementing factories.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
+ public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap)
+ {
+ super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
+ + "AMQ SASL providers that want to be registered");
+ register(providerMap);
+ }
+
+ /**
+ * Registers client factory classes for a map of mechanism names to client factory classes.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
+ private void register(Map<String, Class<? extends SaslClientFactory>> providerMap)
+ {
+ for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet())
+ {
+ put("SaslClientFactory." + me.getKey(), me.getValue().getName());
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
new file mode 100644
index 0000000000..12090e866a
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.qpid.management.ui.sasl;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class UsernameHashedPasswordCallbackHandler implements CallbackHandler
+{
+ private String user;
+ private char[] pwchars;
+
+ public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception
+ {
+ this.user = user;
+ this.pwchars = getHash(password);
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof NameCallback)
+ {
+ NameCallback ncb = (NameCallback) callbacks[i];
+ ncb.setName(user);
+ }
+ else if (callbacks[i] instanceof PasswordCallback)
+ {
+ PasswordCallback pcb = (PasswordCallback) callbacks[i];
+ pcb.setPassword(pwchars);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callbacks[i]);
+ }
+ }
+ }
+
+ private char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+
+ byte[] data = text.getBytes("utf-8");
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ for (byte b : data)
+ {
+ md.update(b);
+ }
+
+ byte[] digest = md.digest();
+
+ char[] hash = new char[digest.length + 1];
+
+ int index = 0;
+ for (byte b : digest)
+ {
+ index++;
+ hash[index] = (char) b;
+ }
+
+ return hash;
+ }
+
+ private void clearPassword()
+ {
+ if (pwchars != null)
+ {
+ for (int i = 0 ; i < pwchars.length ; i++)
+ {
+ pwchars[i] = 0;
+ }
+ pwchars = null;
+ }
+ }
+
+ protected void finalize()
+ {
+ clearPassword();
+ }
+}