diff options
| author | Bhupendra Bhusman Bhardwaj <bhupendrab@apache.org> | 2007-04-06 14:53:36 +0000 |
|---|---|---|
| committer | Bhupendra Bhusman Bhardwaj <bhupendrab@apache.org> | 2007-04-06 14:53:36 +0000 |
| commit | 9695925198d8584bc503d0ccc96eb3b6935b8889 (patch) | |
| tree | 824a67590f1ad648a353cd0f459fe944ea4250d3 /java | |
| parent | ced9b99d37dc1bff385759e4f6f0358635017689 (diff) | |
| download | qpid-python-9695925198d8584bc503d0ccc96eb3b6935b8889.tar.gz | |
QPID-444 : Enabling the SASL support. jmxmp can be plugged into for SASL.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2@526187 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java')
12 files changed, 446 insertions, 42 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 38a4d4561f..c15bdc4fa0 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,6 +41,7 @@ public abstract class ApplicationRegistry { private static ImageRegistry imageRegistry = new ImageRegistry(); private static FontRegistry fontRegistry = new FontRegistry(); + public static final boolean enableSecurity = Boolean.getBoolean("security"); static { diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java index 5a926e6474..64f5342697 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java @@ -194,9 +194,6 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg } } - //If you create it, you dispose it. - shell.dispose(); - // enable the main shell _window.getShell().setEnabled(true); _window.getShell().open(); @@ -327,11 +324,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg _domain = comboDomain.getText(); _addServer = true; - - if (!connectButton.getShell().isDisposed()) - { - connectButton.getShell().dispose(); - } + shell.dispose(); } }); diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java index 8fe08462cd..e9d81b6a6a 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java @@ -168,9 +168,6 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate } } - //If you create it, you dispose it. - shell.dispose(); - // enable the main shell _window.getShell().setEnabled(true); _window.getShell().open(); @@ -240,11 +237,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate } _connect = true; - - if (!connectButton.getShell().isDisposed()) - { - connectButton.getShell().dispose(); - } + shell.dispose(); } }); 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 b0f9928c38..1bd1d12583 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 java.lang.reflect.Constructor; +import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -36,6 +38,7 @@ import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; +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; @@ -44,10 +47,13 @@ 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.SaslProvider; +import org.apache.qpid.management.ui.sasl.UserPasswordCallbackHandler; public class JMXServerRegistry extends ServerRegistry { + private boolean _securityEnabled = false; private ObjectName _serverObjectName = null; private JMXConnector _jmxc = null; private MBeanServerConnection _mbsc = null; @@ -83,11 +89,47 @@ public class JMXServerRegistry extends ServerRegistry { super(server); JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl()); - Map<String, Object> env = new HashMap<String, Object>(); - String[] creds = {server.getUser(), server.getPassword()}; - env.put(JMXConnector.CREDENTIALS, creds); - - _jmxc = JMXConnectorFactory.connect(jmxUrl, env); + Map<String, Object> env = null; + + //String[] creds = {server.getUser(), server.getPassword()}; + //env.put(JMXConnector.CREDENTIALS, creds); + + if (ApplicationRegistry.enableSecurity) + { + Security.addProvider(new SaslProvider()); + jmxUrl = new JMXServiceURL("jmxmp", null, server.getPort()); + //jmxUrl = new JMXServiceURL("service:jmx:jmxmp://localhost:8999"); + + 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())); + try + { + Class klass = Class.forName("javax.management.remote.jmxmp.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 = new JMXMPConnector(jmxUrl, env); + _jmxc.connect(); + } + catch (Exception ex) + { + // When JMXMPConnector is not available + jmxUrl = new JMXServiceURL(server.getUrl()); + _jmxc = JMXConnectorFactory.connect(jmxUrl, null); + } + } + else + { + jmxUrl = new JMXServiceURL(server.getUrl()); + _jmxc = JMXConnectorFactory.connect(jmxUrl, null); + } + _mbsc = _jmxc.getMBeanServerConnection(); _clientListener = new ClientListener(server); 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 5ceeb879b4..6c34ec9898 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 @@ -149,27 +149,27 @@ public class MBeanUtility * @param mbean managed bean * @param ex Exception */ - public static void handleException(ManagedBean mbean, Exception ex) + public static void handleException(ManagedBean mbean, Throwable ex) { if (mbean == null) { ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof IOException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "IO Error occured \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof ReflectionException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof InstanceNotFoundException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof MBeanException) { @@ -188,8 +188,20 @@ public class MBeanUtility } else { - ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage()); - ex.printStackTrace(); + if (ex.getCause() != null) + { + handleException(mbean, ex.getCause()); + } + else + { + String msg = ex.getMessage(); + if (msg == null) + { + msg = ex.toString(); + } + ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg); + printStackTrace(ex); + } } } @@ -457,4 +469,12 @@ public class MBeanUtility { return _debug; } + + private static void printStackTrace(Throwable ex) + { + if (isDebug()) + { + ex.printStackTrace(); + } + } } diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java new file mode 100644 index 0000000000..ce9a273eaa --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java @@ -0,0 +1,54 @@ +/* + * + * 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.SaslClient; +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslException; + +public class ClientSaslFactory implements SaslClientFactory +{ + public SaslClient createSaslClient(String[] mechs, String authorizationId, String protocol, + String serverName, Map props, CallbackHandler cbh) + throws SaslException + { + for (int i = 0; i < mechs.length; i++) + { + if (mechs[i].equals("PLAIN")) + { + return new PlainSaslClient(authorizationId, cbh); + } + } + return null; + } + + /** + * Simple-minded implementation that ignores props + */ + public String[] getMechanismNames(Map props) + { + return new String[]{"PLAIN"}; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java new file mode 100644 index 0000000000..22190f29eb --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java @@ -0,0 +1,203 @@ +/* + * + * 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.*; +import javax.security.auth.callback.*; +import javax.security.sasl.*; + +public class PlainSaslClient implements SaslClient +{ + + private boolean completed; + private CallbackHandler cbh; + private String authorizationID; + private String authenticationID; + private byte password[]; + private static byte SEPARATOR = 0; + + public PlainSaslClient(String authorizationID, CallbackHandler cbh) throws SaslException + { + completed = false; + this.cbh = cbh; + Object[] userInfo = getUserInfo(); + this.authorizationID = authorizationID; + this.authenticationID = (String) userInfo[0]; + this.password = (byte[]) userInfo[1]; + if (authenticationID == null || password == null) + { + throw new SaslException("PLAIN: authenticationID and password must be specified"); + } + } + + public byte[] evaluateChallenge(byte[] challenge) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: authentication already " + + "completed"); + } + completed = true; + try + { + byte authzid[] = + authorizationID == null ? null : authorizationID.getBytes("UTF8"); + byte authnid[] = authenticationID.getBytes("UTF8"); + byte response[] = + new byte[ + password.length + + authnid.length + + 2 + // SEPARATOR + (authzid != null ? authzid.length : 0) + ]; + int size = 0; + if (authzid != null) { + System.arraycopy(authzid, 0, response, 0, authzid.length); + size = authzid.length; + } + response[size++] = SEPARATOR; + System.arraycopy(authnid, 0, response, size, authnid.length); + size += authnid.length; + response[size++] = SEPARATOR; + System.arraycopy(password, 0, response, size, password.length); + clearPassword(); + return response; + } catch (UnsupportedEncodingException e) { + throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids", + e); + } + } + + public String getMechanismName() + { + return "PLAIN"; + } + + public boolean hasInitialResponse() + { + return true; + } + + public boolean isComplete() + { + return completed; + } + + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + if (completed) { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } else { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public Object getNegotiatedProperty(String propName) + { + if (completed) + { + if (propName.equals(Sasl.QOP)) + { + return "auth"; + } + else + { + return null; + } + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + private void clearPassword() + { + if (password != null) + { + for (int i = 0 ; i < password.length ; i++) + { + password[i] = 0; + } + password = null; + } + } + + public void dispose() throws SaslException + { + clearPassword(); + } + + protected void finalize() + { + clearPassword(); + } + + private Object[] getUserInfo() throws SaslException + { + try + { + final String userPrompt = "PLAIN authentication id: "; + final String pwPrompt = "PLAIN password: "; + NameCallback nameCb = new NameCallback(userPrompt); + PasswordCallback passwordCb = new PasswordCallback(pwPrompt, false); + cbh.handle(new Callback[] { nameCb, passwordCb }); + String userid = nameCb.getName(); + char pwchars[] = passwordCb.getPassword(); + byte pwbytes[]; + if (pwchars != null) + { + pwbytes = (new String(pwchars)).getBytes("UTF8"); + passwordCb.clearPassword(); + } + else + { + pwbytes = null; + } + return (new Object[] { userid, pwbytes }); + } + catch (IOException e) + { + throw new SaslException("Cannot get password", e); + } + catch (UnsupportedCallbackException e) + { + throw new SaslException("Cannot get userid/password", e); + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java new file mode 100644 index 0000000000..2917de8740 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java @@ -0,0 +1,35 @@ +/* + * + * 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; + +public class SaslProvider extends Provider +{ + private static final long serialVersionUID = -6978096016899676466L; + + public SaslProvider() + { + super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM"); + put("SaslClientFactory.PLAIN", "ClientSaslFactory"); + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java new file mode 100644 index 0000000000..1602229c85 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java @@ -0,0 +1,73 @@ +/* + * 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.*; +import javax.security.auth.callback.*; + +public class UserPasswordCallbackHandler implements CallbackHandler +{ + private String user; + private char[] pwchars; + + public UserPasswordCallbackHandler(String user, String password) + { + this.user = user; + this.pwchars = password.toCharArray(); + } + + 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 void clearPassword() + { + if (pwchars != null) + { + for (int i = 0 ; i < pwchars.length ; i++) + { + pwchars[i] = 0; + } + pwchars = null; + } + } + + protected void finalize() + { + clearPassword(); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java index a861405d30..48fcd35b12 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -244,7 +244,8 @@ public class NavigationView extends ViewPart List<TreeObject> list = _serversRootNode.getChildren(); for (TreeObject node : list) { - if (url.equals(node.getUrl())) + ManagedServer nodeServer = (ManagedServer)node.getManagedObject(); + if (url.equals(nodeServer.getUrl())) { // Server is already in the list of added servers, so now connect it. // Set the server node as selected and then connect it. @@ -266,7 +267,6 @@ public class NavigationView extends ViewPart // Server connection is successful. Now add the server in the tree TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER); - serverNode.setUrl(url); serverNode.setManagedObject(managedServer); _serversRootNode.addChild(serverNode); diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java index 49b61c0fc6..5847d26e3b 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java @@ -530,6 +530,8 @@ public class OperationTabControl extends TabControl ((org.eclipse.swt.widgets.List)controls[i]).deselectAll(); else if (controls[i] instanceof Text) ((Text)controls[i]).setText(""); + else if (controls[i] instanceof Button) + ((Button)controls[i]).setSelection(false); else if (controls[i] instanceof Composite) clearParameterValues((Composite)controls[i]); } diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java index 511c2d7150..9545ed9876 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java @@ -31,7 +31,6 @@ public class TreeObject { private String _name; private String _type; - private String _url; private String _virtualHost; private TreeObject _parent; private List<TreeObject> _children = new ArrayList<TreeObject>(); @@ -88,16 +87,6 @@ public class TreeObject { return _type; } - - public String getUrl() - { - return _url; - } - - public void setUrl(String url) - { - this._url = url; - } public String getVirtualHost() { @@ -131,7 +120,6 @@ public class TreeObject if (parent != null) { - this._url = parent.getUrl(); parent.addChild(this); } } |
