/*
* Copyright (C) The MX4J Contributors.
* All rights reserved.
*
* This software is distributed under the terms of the MX4J License version 1.0.
* See the terms of the MX4J License in the documentation provided with this software.
*/
package test.javax.management.remote;
import java.net.MalformedURLException;
import java.net.SocketPermission;
import java.security.AccessController;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.Principal;
import java.security.ProtectionDomain;
import java.security.SecurityPermission;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanPermission;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServerPermission;
import javax.management.MBeanTrustPermission;
import javax.management.ObjectName;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXPrincipal;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.SubjectDelegationPermission;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
import junit.framework.TestCase;
import mx4j.remote.MX4JRemoteUtils;
import mx4j.server.MX4JMBeanServer;
import test.javax.management.SecurityManagerTestCase;
/**
* @version $Revision: 1.4 $
*/
public abstract class RemoteSecurityManagerTestCase extends SecurityManagerTestCase
{
public RemoteSecurityManagerTestCase(String s)
{
super(s);
}
protected void setUp() throws Exception
{
// Be sure we have a security manager and the right policy
SecurityManager sm = System.getSecurityManager();
if (sm == null) fail();
Policy policy = Policy.getPolicy();
if (!(policy instanceof RemoteModifiablePolicy)) fail();
((RemoteModifiablePolicy)policy).initialize();
}
protected void tearDown() throws Exception
{
// Allow the sockets to shut down
sleep(2000);
}
protected void addPermission(Permission p)
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
policy.addServerPermission(p);
}
protected void resetPermissions()
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
policy.initialize();
}
/**
* Creates and returns a suitable JMXServiceURL for the specific JMXConnectorServer
* used in the tests. Subclasses implements it to return specific JMXServiceURL.
*/
protected abstract JMXServiceURL createJMXConnectorServerAddress() throws MalformedURLException;
/**
* Creates and returns a new environment map to be used for the server side
*
* @see #createClientEnvironment
*/
protected Map createServerEnvironment()
{
return new HashMap();
}
/**
* Creates and returns a new environment map to be used for the client side
*
* @see #createServerEnvironment
*/
protected Map createClientEnvironment()
{
return new HashMap();
}
public void testNewJMXConnectorServer() throws Exception
{
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
try
{
cntorServer.start();
fail();
}
catch (SecurityException x)
{
}
}
public void testStartJMXConnectorServer() throws Exception
{
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
try
{
cntorServer.start();
}
finally
{
cntorServer.stop();
}
}
public void testConnect() throws Exception
{
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
JMXConnector cntor = null;
try
{
cntorServer.start();
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
policy.setSeparateClientServerPermissions(true);
try
{
JMXConnectorFactory.connect(cntorServer.getAddress());
fail();
}
catch (SecurityException x)
{
}
// Allow any client to connect to the server
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
// Allow this client to open a socket to connect to the server
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress());
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testAuthenticatedConnect() throws Exception
{
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
Map serverEnv = createServerEnvironment();
serverEnv.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator()
{
public Subject authenticate(Object credentials) throws SecurityException
{
if (!(credentials instanceof String[])) throw new SecurityException("No credentials provided");
String[] creds = (String[])credentials;
if (creds.length != 2) throw new SecurityException("Bad credentials");
String user = creds[0];
String password = creds[1];
if (!"test".equals(user)) throw new SecurityException("Unknown user");
if (!"test".equals(password)) throw new SecurityException("Wrong password");
Principal principal = new JMXPrincipal(user);
Set principals = new HashSet();
principals.add(principal);
Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
return subject;
}
});
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, serverEnv, newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
policy.setSeparateClientServerPermissions(true);
Map clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"test", "test"});
// Allow this client to open a socket to connect to the server
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
// Allow the authenticated subject to listen and accept a connection
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("localhost:" + url.getPort(), "listen"));
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("*:1024-" + url.getPort(), "accept"));
// No credentials
try
{
JMXConnectorFactory.connect(cntorServer.getAddress());
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, null);
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new StringBuffer());
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[0]);
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"dummy"});
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"dummy", "dummy"});
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"dummy", "dummy", "dummy"});
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
// Bad credentials
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"test", "wrong"});
try
{
JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
fail();
}
catch (SecurityException x)
{
}
clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"test", "test"});
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testAuthenticatedSubjectOnServerSide() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
Map serverEnv = createServerEnvironment();
serverEnv.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator()
{
public Subject authenticate(Object credentials) throws SecurityException
{
if (!(credentials instanceof String[])) throw new SecurityException("No credentials provided");
String[] creds = (String[])credentials;
if (creds.length != 2) throw new SecurityException("Bad credentials");
String user = creds[0];
String password = creds[1];
if (!"test".equals(user)) throw new SecurityException("Unknown user");
if (!"test".equals(password)) throw new SecurityException("Wrong password");
Principal principal = new JMXPrincipal(user);
Set principals = new HashSet();
principals.add(principal);
Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
return subject;
}
});
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, serverEnv, newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
Map clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"test", "test"});
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
policy.addServerPermission(new JMXPrincipal("test"), new AuthPermission("doAsPrivileged"));
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("localhost:" + url.getPort(), "listen"));
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
addPermission(new MBeanTrustPermission("*"));
policy.addServerPermission(new JMXPrincipal("test"), new MBeanPermission("*", "instantiate, registerMBean, getAttribute"));
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
ObjectName name = ObjectName.getInstance(":name=subject");
cntion.createMBean(SubjectCheck.class.getName(), name, null);
policy.addServerPermission(new JMXPrincipal("test"), new AuthPermission("getSubject"));
Subject subject = (Subject)cntion.getAttribute(name, "Subject");
Set principals = subject.getPrincipals();
assertNotNull(principals);
assertEquals(principals.size(), 1);
Principal principal = (Principal)principals.iterator().next();
assertTrue(principal instanceof JMXPrincipal);
assertEquals(principal.getName(), "test");
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testDelegateSubjectOnServerSide() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
Map serverEnv = createServerEnvironment();
serverEnv.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator()
{
public Subject authenticate(Object credentials) throws SecurityException
{
if (!(credentials instanceof String[])) throw new SecurityException("No credentials provided");
String[] creds = (String[])credentials;
if (creds.length != 2) throw new SecurityException("Bad credentials");
String user = creds[0];
String password = creds[1];
if (!"test".equals(user)) throw new SecurityException("Unknown user");
if (!"test".equals(password)) throw new SecurityException("Wrong password");
Principal principal = new JMXPrincipal(user);
Set principals = new HashSet();
principals.add(principal);
Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
return subject;
}
});
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, serverEnv, newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
Map clientEnv = createClientEnvironment();
clientEnv.put(JMXConnector.CREDENTIALS, new String[]{"test", "test"});
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
policy.addServerPermission(new JMXPrincipal("test"), new AuthPermission("doAsPrivileged"));
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("localhost:" + url.getPort(), "listen"));
policy.addServerPermission(new JMXPrincipal("test"), new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), clientEnv);
addPermission(new MBeanTrustPermission("*"));
policy.addServerPermission(new JMXPrincipal("delegate"), new MBeanPermission("*", "instantiate, registerMBean, getAttribute"));
policy.addServerPermission(new JMXPrincipal("test"), new SubjectDelegationPermission(JMXPrincipal.class.getName() + ".delegate"));
Set delegates = new HashSet();
delegates.add(new JMXPrincipal("delegate"));
Subject delegate = new Subject(true, delegates, Collections.EMPTY_SET, Collections.EMPTY_SET);
MBeanServerConnection cntion = cntor.getMBeanServerConnection(delegate);
ObjectName name = ObjectName.getInstance(":name=subject");
cntion.createMBean(SubjectCheck.class.getName(), name, null);
policy.addServerPermission(new JMXPrincipal("delegate"), new AuthPermission("getSubject"));
Subject subject = (Subject)cntion.getAttribute(name, "Subject");
Set principals = subject.getPrincipals();
assertNotNull(principals);
assertEquals(principals.size(), 1);
Principal principal = (Principal)principals.iterator().next();
assertTrue(principal instanceof JMXPrincipal);
assertEquals(principal.getName(), "delegate");
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testAddRemoveNotificationListener() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testAddRemoveNotificationListener(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testCreateMBean4Params() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testCreateMBean4Params(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testCreateMBean5Params() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testCreateMBean5Params(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetAttribute() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetAttribute(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetAttributes() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetAttributes(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetDefaultDomain() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
String domain = "xxx";
MBeanServer server = MBeanServerFactory.newMBeanServer(domain);
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), server);
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetDefaultDomain(cntion, domain);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetDomains() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetDomains(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetMBeanCount() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetMBeanCount(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetMBeanInfo() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetMBeanInfo(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testGetObjectInstance() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testGetObjectInstance(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testInvoke() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testInvoke(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testIsInstanceOf() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testIsInstanceOf(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testIsRegistered() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testIsRegistered(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testQueryMBeans() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testQueryMBeans(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testQueryNames() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testQueryNames(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testSetAttribute() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testSetAttribute(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testSetAttributes() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testSetAttributes(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public void testUnregisterMBean() throws Exception
{
RemoteModifiablePolicy policy = (RemoteModifiablePolicy)Policy.getPolicy();
addPermission(new MBeanServerPermission("newMBeanServer"));
JMXServiceURL url = createJMXConnectorServerAddress();
JMXConnectorServer cntorServer = null;
JMXConnector cntor = null;
try
{
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, createServerEnvironment(), newMBeanServer());
// Required by the server
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
cntorServer.start();
policy.setSeparateClientServerPermissions(true);
policy.addClientPermission(new SocketPermission("localhost:" + url.getPort(), "connect"));
addPermission(new SocketPermission("localhost:" + url.getPort(), "listen"));
addPermission(new SocketPermission("*:1024-" + url.getPort(), "accept"));
cntor = JMXConnectorFactory.connect(cntorServer.getAddress(), createClientEnvironment());
MBeanServerConnection cntion = cntor.getMBeanServerConnection();
testUnregisterMBean(cntion);
}
finally
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
}
public interface SubjectCheckMBean
{
public Subject getSubject();
}
public static class SubjectCheck implements SubjectCheckMBean
{
public Subject getSubject()
{
return Subject.getSubject(AccessController.getContext());
}
}
/**
* A modifiable policy that allow permissions to be added at runtime, used for tests purposes only.
*/
public abstract static class RemoteModifiablePolicy extends Policy
{
private final ProtectionDomain testDomain;
private final Map serverPermissions = new HashMap();
private final Map clientPermissions = new HashMap();
private final Map principalPermissions = new HashMap();
private volatile boolean separated;
public RemoteModifiablePolicy()
{
// Here we still have no security manager installed
testDomain = RemoteModifiablePolicy.class.getProtectionDomain();
// Add the permissions needed to run the tests
CodeSource junitCodeSource = TestCase.class.getProtectionDomain().getCodeSource();
serverPermissions.put(junitCodeSource, createAllPermissions());
clientPermissions.put(junitCodeSource, createAllPermissions());
CodeSource mx4jCodeSource = MBeanServerFactory.class.getProtectionDomain().getCodeSource();
serverPermissions.put(mx4jCodeSource, createAllPermissions());
clientPermissions.put(mx4jCodeSource, createAllPermissions());
CodeSource implCodeSource = MX4JMBeanServer.class.getProtectionDomain().getCodeSource();
serverPermissions.put(implCodeSource, createAllPermissions());
clientPermissions.put(implCodeSource, createAllPermissions());
CodeSource rmx4jCodeSource = JMXConnector.class.getProtectionDomain().getCodeSource();
serverPermissions.put(rmx4jCodeSource, createAllPermissions());
clientPermissions.put(rmx4jCodeSource, createAllPermissions());
CodeSource rimplCodeSource = MX4JRemoteUtils.class.getProtectionDomain().getCodeSource();
serverPermissions.put(rimplCodeSource, createAllPermissions());
clientPermissions.put(rimplCodeSource, createAllPermissions());
ClassLoader loader = getClass().getClassLoader();
// BCEL
try
{
Class cls = loader.loadClass("org.apache.bcel.generic.Type");
CodeSource bcelCodeSource = cls.getProtectionDomain().getCodeSource();
serverPermissions.put(bcelCodeSource, createAllPermissions());
clientPermissions.put(bcelCodeSource, createAllPermissions());
}
catch (ClassNotFoundException ignored)
{
}
// When we run automated, we need also permissions for Ant jars
try
{
Class cls = loader.loadClass("org.apache.tools.ant.Task");
CodeSource antCodeSource = cls.getProtectionDomain().getCodeSource();
serverPermissions.put(antCodeSource, createAllPermissions());
clientPermissions.put(antCodeSource, createAllPermissions());
cls = loader.loadClass("org.apache.tools.ant.taskdefs.optional.junit.JUnitTask");
antCodeSource = cls.getProtectionDomain().getCodeSource();
serverPermissions.put(antCodeSource, createAllPermissions());
clientPermissions.put(antCodeSource, createAllPermissions());
}
catch (ClassNotFoundException ignored)
{
}
mapServerPermissions(serverPermissions);
initialize();
}
/**
* Callback for subclasses to add more mappings between a codesource and
* (normally) a Permissions object containing AllPermission.
* This is necessary if the implementation of the JMXConnectorServer needs additional
* jars such as for example commons-logging.jar, whose codesource is normally mapped
* with AllPermission.
*
* @see #createAllPermissions
*/
protected void mapServerPermissions(Map permissions)
{
// Nothing necessary here
}
/**
* Creates and returns a Permissions object containing AllPermission.
*
* @see #mapServerPermissions
*/
protected Permissions createAllPermissions()
{
Permissions allPermissions = new Permissions();
allPermissions.add(new AllPermission());
return allPermissions;
}
/**
* Returns whether the current thread is a server side thread or
* a client side thread.
* Subclasses implement this method by for example looking at the thread name.
*
* @see #setSeparateClientServerPermissions
* @see #isSeparateClientServerPermissions
*/
public abstract boolean isServerSide();
public PermissionCollection getPermissions(CodeSource codesource)
{
return getPermissions(codesource, isServerSide());
}
private synchronized PermissionCollection getPermissions(CodeSource codesource, boolean serverside)
{
if (serverside)
{
PermissionCollection perms = (PermissionCollection)serverPermissions.get(codesource);
if (perms == null) perms = new Permissions();
perms = copyIfReadOnly(perms);
serverPermissions.put(codesource, perms);
return perms;
}
else
{
PermissionCollection perms = (PermissionCollection)clientPermissions.get(codesource);
if (perms == null) perms = new Permissions();
perms = copyIfReadOnly(perms);
clientPermissions.put(codesource, perms);
return perms;
}
}
/**
* For JDK 1.4 overriding this method disables caching of Permissions done by the
* standard Policy implementation.
* This is done because we install this policy *before* installing the security manager.
* By doing so, in JDK 1.4 the permissions granted at the moment of policy installation
* (no security manager == AllPermission) are cached and will invalidate all tests, since
* they will become unmodifiable.
* <p/>
* The stack trace is when checking a permission is:
* <p/>
* SecurityManager.checkPermission()
* AccessController.checkPermission()
* AccessControlContext.checkPermission()
* ProtectionDomain.implies()
* RemoteModifiablePolicy.implies()
*/
public boolean implies(ProtectionDomain domain, Permission permission)
{
Principal[] principals = domain.getPrincipals();
boolean injectedDomain = false;
CodeSource cs = domain.getCodeSource();
if (principals != null && principals.length > 0 && cs != null && cs.getLocation() == null && domain.getClassLoader() == null) injectedDomain = true;
if (!injectedDomain)
{
PermissionCollection perms = getPermissions(cs);
boolean result = perms.implies(permission);
// System.out.println("Policy.implies, side is " + (isServerSide() ? "server" : "client") + " codesource " + cs + " on " + permission + " over " + perms + ": " + result);
return result;
}
else
{
for (int i = 0; i < principals.length; ++i)
{
Principal principal = principals[i];
PermissionCollection perms = getPrincipalPermissions(principal);
if (perms.implies(permission)) return true;
}
return false;
}
}
private synchronized PermissionCollection getPrincipalPermissions(Principal principal)
{
PermissionCollection perms = (PermissionCollection)principalPermissions.get(principal);
if (perms == null) perms = new Permissions();
perms = copyIfReadOnly(perms);
principalPermissions.put(principal, perms);
return perms;
}
public void refresh()
{
}
/**
* Adds the given permission to the client (the test in this case) codesource,
* on server side
*/
public void addServerPermission(Permission p)
{
Permissions permissions = (Permissions)getPermissions(testDomain.getCodeSource(), true);
permissions.add(p);
}
/**
* Adds the given permission to the client (the test in this case) codesource,
* on client side
*/
public void addClientPermission(Permission p)
{
Permissions permissions = (Permissions)getPermissions(testDomain.getCodeSource(), false);
permissions.add(p);
}
/**
* Adds the given permission to the JSR 160 injected codesource,
* on server side, for the given principal
*/
public void addServerPermission(Principal principal, Permission p)
{
Permissions permissions = (Permissions)getPrincipalPermissions(principal);
permissions.add(p);
addServerPermission(p);
}
/**
* Initializes the permissions for the client (the test in this case) codesource,
* and marks this policy as working on server side.
*
* @see #setSeparateClientServerPermissions
*/
public synchronized void initialize()
{
Permissions permissions = new Permissions();
permissions.add(new SecurityPermission("getPolicy"));
serverPermissions.put(testDomain.getCodeSource(), permissions);
permissions = new Permissions();
permissions.add(new SecurityPermission("getPolicy"));
clientPermissions.put(testDomain.getCodeSource(), permissions);
principalPermissions.clear();
setSeparateClientServerPermissions(false);
}
/**
* Tells this policy to distinguish the check of permissions basing on the fact
* that the thread is a server side thread or a client side thread.
*
* @see #isServerSide
* @see #isSeparateClientServerPermissions
*/
public synchronized void setSeparateClientServerPermissions(boolean value)
{
separated = value;
}
/**
* Returns if this policy distinguishes between server side and client side
* permission checking.
*
* @see #setSeparateClientServerPermissions
*/
protected synchronized boolean isSeparateClientServerPermissions()
{
return separated;
}
/**
* The RMI marshalling mechanism (and this is only one place I have discovered so far)
* sometimes marks the PermissionCollection as read-only via
* {@link PermissionCollection#setReadOnly}. Since this policy
* adds permissions at runtime, having the Permissions object marked as read-only
* causes an exception that invalidates the test.
* Here I copy the read-only Permissions into a new Permissions object (by copying
* all permissions it contains into the copied object), and return it.
* If the Permissions object is not read-only, it is returned immediately.
*/
private PermissionCollection copyIfReadOnly(PermissionCollection p)
{
if (!p.isReadOnly()) return p;
Permissions permissions = new Permissions();
for (Enumeration e = p.elements(); e.hasMoreElements();)
{
Permission permission = (Permission)e.nextElement();
permissions.add(permission);
}
return permissions;
}
}
}