You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ri...@apache.org on 2007/04/20 15:25:50 UTC
svn commit: r530798 - in
/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server:
management/ security/access/
Author: ritchiem
Date: Fri Apr 20 06:25:50 2007
New Revision: 530798
URL: http://svn.apache.org/viewvc?view=rev&rev=530798
Log:
QPID-445 Added checks to ensure UserManagement MBean is only accessed by Admin users.
Allow Qpid JMX Management console to manage access file.
Modified:
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
Modified: incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java?view=diff&rev=530798&r1=530797&r2=530798
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java (original)
+++ incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java Fri Apr 20 06:25:50 2007
@@ -83,7 +83,7 @@
}
- public void start()
+ public void start() throws IOException
{
// Check if the "QPID_OPTS" is set to use Out of the Box JMXAgent
if (areOutOfTheBoxJMXOptionsSet())
@@ -97,76 +97,60 @@
boolean security = appRegistry.getConfiguration().getBoolean("management.security-enabled", true);
int port = appRegistry.getConfiguration().getInt("management.jmxport", 8999);
- try
+ if (security)
{
- if (security)
- {
- // For SASL using JMXMP
- _jmxURL = new JMXServiceURL("jmxmp", null, port);
+ // For SASL using JMXMP
+ _jmxURL = new JMXServiceURL("jmxmp", null, port);
- Map env = new HashMap();
- Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
- PrincipalDatabase db = null;
-
- for (Map.Entry<String, PrincipalDatabase> entry : map.entrySet())
- {
- if (entry.getValue() instanceof Base64MD5PasswordFilePrincipalDatabase)
- {
- db = entry.getValue();
- break;
- }
- else if (entry.getValue() instanceof PlainPasswordFilePrincipalDatabase)
- {
- db = entry.getValue();
- }
- }
-
- if (db instanceof Base64MD5PasswordFilePrincipalDatabase)
- {
- env.put("jmx.remote.profiles", "SASL/CRAM-MD5");
- CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser();
- initialiser.initialise(db);
- env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler());
- }
- else if (db instanceof PlainPasswordFilePrincipalDatabase)
- {
- env.put("jmx.remote.profiles", "SASL/PLAIN");
- env.put("jmx.remote.sasl.callback.handler", new UserCallbackHandler(db));
- }
-
- // Enable the SSL security and server authentication
- /*
- SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
- SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
- env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
- env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
- */
+ Map env = new HashMap();
+ Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
+ PrincipalDatabase db = null;
- try
+ for (Map.Entry<String, PrincipalDatabase> entry : map.entrySet())
+ {
+ if (entry.getValue() instanceof Base64MD5PasswordFilePrincipalDatabase)
+ {
+ db = entry.getValue();
+ break;
+ }
+ else if (entry.getValue() instanceof PlainPasswordFilePrincipalDatabase)
{
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, env, _mbeanServer);
- MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
- cs.setMBeanServerForwarder(mbsf);
- cs.start();
- _log.info("JMX: Starting JMXConnector server with SASL");
- }
- catch (java.net.MalformedURLException urlException)
- {
- // When JMXMPConnector is not available
- // java.net.MalformedURLException: Unsupported protocol: jmxmp
- _log.info("JMX: Starting JMXConnector server");
- startJMXConnectorServer(port);
+ db = entry.getValue();
}
}
- else
+
+ if (db instanceof Base64MD5PasswordFilePrincipalDatabase)
+ {
+ env.put("jmx.remote.profiles", "SASL/CRAM-MD5");
+ CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser();
+ initialiser.initialise(db);
+ env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler());
+ }
+ else if (db instanceof PlainPasswordFilePrincipalDatabase)
{
- startJMXConnectorServer(port);
+ env.put("jmx.remote.profiles", "SASL/PLAIN");
+ env.put("jmx.remote.sasl.callback.handler", new UserCallbackHandler(db));
}
+
+ // Enable the SSL security and server authentication
+ /*
+ SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
+ SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
+ env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
+ */
+
+ JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, env, _mbeanServer);
+ MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
+ cs.setMBeanServerForwarder(mbsf);
+ cs.start();
+ _log.warn("JMX: Started JMXConnector server with SASL");
+
}
- catch (Exception ex)
+ else
{
- _log.error("Error in initialising Managed Object Registry." + ex.getMessage());
- ex.printStackTrace();
+ startJMXConnectorServer(port);
+ _log.warn("JMX: Started JMXConnector server with security disabled");
}
}
@@ -280,7 +264,7 @@
String username = ncb.getDefaultName();
try
{
- authorized = _principalDatabase.verifyPassword(username, new String(pcb.getPassword()));
+ authorized = _principalDatabase.verifyPassword(username, pcb.getPassword());
}
catch (AccountNotFoundException e)
{
Modified: incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java?view=diff&rev=530798&r1=530797&r2=530798
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java (original)
+++ incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java Fri Apr 20 06:25:50 2007
@@ -18,6 +18,7 @@
package org.apache.qpid.server.management;
import org.apache.qpid.AMQException;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
import org.apache.log4j.Logger;
import javax.management.remote.MBeanServerForwarder;
@@ -122,8 +123,20 @@
Principal principal = principals.iterator().next();
String identity = principal.getName();
+ if (isAdminMethod(args))
+ {
+ if (isAdmin(identity))
+ {
+ return method.invoke(mbs, args);
+ }
+ else
+ {
+ throw new SecurityException("Access denied");
+ }
+ }
+
// Following users can perform any operation other than "createMBean" and "unregisterMBean"
- if (isAdmin(identity) || isAllowedToModify(identity))
+ if (isAllowedToModify(identity))
{
return method.invoke(mbs, args);
}
@@ -138,6 +151,41 @@
throw new SecurityException("Access denied");
}
+ private boolean isAdminMethod(Object[] args)
+ {
+ if (args[0] instanceof ObjectName)
+ {
+ String mbeanMethod = (args.length > 1) ? (String) args[1] : null;
+ if (mbeanMethod == null)
+ {
+ if (args[0] instanceof ObjectName)
+ {
+ ObjectName object = (ObjectName) args[0];
+ return object.getCanonicalName().contains("UserManagement");
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ try
+ {
+ MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]);
+ if (mbeanInfo != null)
+ {
+ return mbeanInfo.getClassName().equals("org.apache.qpid.server.security.access.AMQUserManagementMBean");
+ }
+ }
+ catch (JMException ex)
+ {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
// Initialises the user roles
public static void setAccessRights(Properties accessRights)
{
@@ -155,7 +203,8 @@
private boolean isAllowedToModify(String userName)
{
- if (READWRITE.equals(_userRoles.getProperty(userName)))
+ if (ADMIN.equals(_userRoles.getProperty(userName))
+ || READWRITE.equals(_userRoles.getProperty(userName)))
{
return true;
}
Modified: incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java?view=diff&rev=530798&r1=530797&r2=530798
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java (original)
+++ incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java Fri Apr 20 06:25:50 2007
@@ -7,9 +7,9 @@
* 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
@@ -22,6 +22,7 @@
import javax.management.JMException;
import java.rmi.RemoteException;
+import java.io.IOException;
/**
* Handles the registration (and unregistration and so on) of managed objects.
@@ -37,7 +38,7 @@
*/
public interface ManagedObjectRegistry
{
- void start();
+ void start() throws IOException;
void registerObject(ManagedObject managedObject) throws JMException;
Modified: incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java?view=diff&rev=530798&r1=530797&r2=530798
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java (original)
+++ incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java Fri Apr 20 06:25:50 2007
@@ -30,6 +30,7 @@
import org.apache.commons.configuration.ConfigurationException;
import javax.management.JMException;
+import javax.management.remote.JMXPrincipal;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
@@ -40,6 +41,7 @@
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.security.auth.login.AccountNotFoundException;
+import javax.security.auth.Subject;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -47,8 +49,11 @@
import java.util.Properties;
import java.util.List;
import java.util.Enumeration;
+import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.security.Principal;
+import java.security.AccessControlContext;
+import java.security.AccessController;
/** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */
@MBeanDescription("User Management Interface")
@@ -250,8 +255,6 @@
// Table of users
// Username(string), Access rights Read,Write,Admin(bool,bool,bool)
- reloadData();
-
if (_userlistDataType == null)
{
_logger.warn("TabluarData not setup correctly");
@@ -411,7 +414,7 @@
rights.renameTo(old);
FileOutputStream output = new FileOutputStream(tmp);
- _accessRights.store(output, "");
+ _accessRights.store(output, "Last edited by user:" + getCurrentJMXUser());
output.close();
// Rename new file to main file
@@ -432,6 +435,22 @@
_accessRightsUpdate.unlock();
}
}
+ }
+
+ private String getCurrentJMXUser()
+ {
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+
+ // Retrieve JMXPrincipal from Subject
+ Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
+ if (principals == null || principals.isEmpty())
+ {
+ return "Unknown user principals were null";
+ }
+
+ Principal principal = principals.iterator().next();
+ return principal.getName();
}
/**
Modified: incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java?view=diff&rev=530798&r1=530797&r2=530798
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java (original)
+++ incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java Fri Apr 20 06:25:50 2007
@@ -28,6 +28,7 @@
import javax.management.openmbean.TabularData;
import javax.management.openmbean.CompositeData;
import javax.management.JMException;
+import javax.management.MBeanOperationInfo;
import java.io.IOException;
public interface UserManagement
@@ -43,7 +44,8 @@
*
* @return The result of the operation
*/
- @MBeanOperation(name = "setPassword", description = "Set password for user.")
+ @MBeanOperation(name = "setPassword", description = "Set password for user.",
+ impact = MBeanOperationInfo.ACTION)
boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
@MBeanOperationParameter(name = "password", description = "Password")char[] password);
@@ -57,7 +59,8 @@
*
* @return The result of the operation
*/
- @MBeanOperation(name = "setRights", description = "Set access rights for user.")
+ @MBeanOperation(name = "setRights", description = "Set access rights for user.",
+ impact = MBeanOperationInfo.ACTION)
boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
@MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
@MBeanOperationParameter(name = "write", description = "Administration write")boolean write,
@@ -74,7 +77,8 @@
*
* @return The result of the operation
*/
- @MBeanOperation(name = "createUser", description = "Create new user from system.")
+ @MBeanOperation(name = "createUser", description = "Create new user from system.",
+ impact = MBeanOperationInfo.ACTION)
boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
@MBeanOperationParameter(name = "password", description = "Password")char[] password,
@MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
@@ -88,7 +92,8 @@
*
* @return The result of the operation
*/
- @MBeanOperation(name = "deleteUser", description = "Delete user from system.")
+ @MBeanOperation(name = "deleteUser", description = "Delete user from system.",
+ impact = MBeanOperationInfo.ACTION)
boolean deleteUser(@MBeanOperationParameter(name = "username", description = "Username")String username);
@@ -97,15 +102,17 @@
*
* @return The result of the operation
*/
-// @MBeanOperation(name = "reloadData", description = "Reload the authentication file from disk.")
-// boolean reloadData();
+ @MBeanOperation(name = "reloadData", description = "Reload the authentication file from disk.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean reloadData();
/**
* View users returns all the users that are currently available to the system.
*
* @return a table of users data (Username, read, write, admin)
*/
- @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.")
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.",
+ impact = MBeanOperationInfo.ACTION)
TabularData viewUsers();
}