dev/null |binary modules/enterprise/server/client-api/pom.xml | 380 ---------- modules/enterprise/server/client-api/src/test/java/org/rhq/enterprise/client/security/test/EjbAccessTest.java | 198 ----- modules/enterprise/server/client-api/src/test/resources/hibernate.properties | 26 modules/enterprise/server/client-api/src/test/resources/security.policy | 10 modules/enterprise/server/itests/pom.xml | 45 + modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/client/security/test/JndiAccessTest.java | 198 +++++ modules/enterprise/server/itests/src/test/resources/embedded-jboss-beans.xml | 10 modules/enterprise/server/itests/src/test/resources/security.policy | 10 9 files changed, 278 insertions(+), 599 deletions(-)
New commits: commit ca98fa5acf8c59902ff3dac98215605a4a455237 Author: Lukas Krejci lkrejci@redhat.com Date: Tue Jan 10 14:25:11 2012 +0100
Moving the JNDI access tests from rhq-server-client-api to rhq-server-itests to reduce the number of tests suites that set up the whole RHQ container.
Made sure to avoid multiple inclusion of the server jar classes on the test classpath (by explicitly excluding the module from the deps of rhq-script-bindings and rhq-server-client-api that the itests module is now dependent on). This caused some weird problems during the embedded container startup.
diff --git a/modules/enterprise/server/client-api/pom.xml b/modules/enterprise/server/client-api/pom.xml index 4dfd109..29ac29a 100644 --- a/modules/enterprise/server/client-api/pom.xml +++ b/modules/enterprise/server/client-api/pom.xml @@ -15,380 +15,32 @@ <name>RHQ Enterprise Server Client API</name> <description>The implementation of the client API when accessing the server locally</description>
- <properties> - <persistence-api.version>1.0</persistence-api.version> - <rhq.server.datasource>java:/RHQDS</rhq.server.datasource> - <rhq.server.ds-mapping>PostgreSQL</rhq.server.ds-mapping> - - <!-- dependency versions --> - <jboss-embeddable-ejb3.version>1.0.0.Alpha9</jboss-embeddable-ejb3.version> - - <clean.db>true</clean.db> - </properties> - - <dependencies> - - <!-- Note, the test deps are intentionally placed above the other scoped deps because of classpath - reasons. Maven orders the [test] classpath in the order listed in the pom. We specifically - need the embeddable-ejb3 jar above the standard ejb3 jars because we need the embeddble packages - loaded when testing. --> - <dependency> - <groupId>jboss.jboss-embeddable-ejb3</groupId> - <artifactId>jboss-ejb3-all</artifactId> - <version>${jboss-embeddable-ejb3.version}</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-script-bindings</artifactId> - <version>${project.version}</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>javax.persistence</groupId> - <artifactId>persistence-api</artifactId> - <version>${persistence-api.version}</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>hibernate-annotations</groupId> - <artifactId>hibernate-annotations</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement - section. --> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-ejb3x</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>provided</scope> <!-- by JBossAS --> - </dependency> - - <!-- Test deps - this insane list of deps is needed to get the embedded JBoss server with RHQ server deployed running --> - + <dependencies> <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>test-utils</artifactId> - <version>${project.version}</version> - <scope>test</scope> + <groupId>org.rhq</groupId> + <artifactId>rhq-container-lib</artifactId> + <version>${project.version}</version> </dependency>
<dependency> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-container-lib</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>hibernate</groupId> - <artifactId>hibernate3</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>hibernate-entitymanager</groupId> - <artifactId>hibernate-entitymanager</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.apache.geronimo.specs</groupId> - <artifactId>geronimo-javamail_1.3.1_spec</artifactId> - <!-- The Sun javamail jar isn't available from a public repo due to licensing issues, - so use the Geronimo one instead. --> - <version>1.3</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - <version>2.4</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>jsp-api</artifactId> - <version>2.0</version> - <scope>test</scope> - </dependency> - - - <dependency> - <groupId>org.opensymphony.quartz</groupId> - <artifactId>quartz</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.opensymphony.quartz</groupId> - <artifactId>quartz-oracle</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-annotations-ejb3</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-cache</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-common</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <!-- includes the org.jboss.ejb3.StrictMaxPool class, which is needed by the PoolClass annotation used on some - of our SLSB's --> - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-ejb3</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${project.version}</version> </dependency>
<dependency> - <groupId>jboss</groupId> - <artifactId>jboss-j2ee</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-jmx</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-system</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jbosssx</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>jboss</groupId> - <artifactId>jbpm</artifactId> - <version>3.1.1</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>antlr</groupId> - <artifactId>antlr</artifactId> - <version>2.7.7</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>javassist</groupId> - <artifactId>javassist</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>trove</groupId> - <artifactId>trove</artifactId> - <version>1.0.2</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>xerces</groupId> - <artifactId>xercesImpl</artifactId> - <version>2.8.1</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>net.sf.opencsv</groupId> - <artifactId>opencsv</artifactId> - <version>1.8</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>commons-jxpath</groupId> - <artifactId>commons-jxpath</artifactId> - <version>1.3</version> - <scope>test</scope> - </dependency> - - <!-- for the transaction interrupt EJB3 interceptor --> - <dependency> - <groupId>org.jboss.transaction</groupId> - <artifactId>jboss-jta</artifactId> - <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> - <scope>test</scope> + <groupId>org.rhq</groupId> + <artifactId>rhq-script-bindings</artifactId> + <version>${project.version}</version> </dependency>
<dependency> - <groupId>tomcat</groupId> - <artifactId>catalina</artifactId> - <version>5.5.20</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>tomcat</groupId> - <artifactId>tomcat-jk</artifactId> - <version>4.1.31</version> - <scope>test</scope> - </dependency> - - <!-- Needed by com.jboss.jbossnetwork.apl.actions.xml.XPathProcessor; TODO: Remove once APL has been excised. --> - <dependency> - <groupId>xalan</groupId> - <artifactId>xalan</artifactId> - <version>2.5.1</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>com.jcraft</groupId> - <artifactId>jsch</artifactId> - <version>0.1.29</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.jboss.resteasy</groupId> - <artifactId>resteasy-jaxrs</artifactId> - <version>${resteasy.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.jboss.resteasy</groupId> - <artifactId>resteasy-jettison-provider</artifactId> - <version>${resteasy.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.jboss.resteasy</groupId> - <artifactId>resteasy-links</artifactId> - <version>${resteasy.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.jboss.el</groupId> - <artifactId>jboss-el</artifactId> - <version>2.0.1.GA</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.freemarker</groupId> - <artifactId>freemarker</artifactId> - <version>2.3.18</version> - <scope>test</scope> - </dependency> - - </dependencies> - - <build> - <testResources> - <testResource> - <directory>src/test/resources</directory> - <filtering>true</filtering> - </testResource> - </testResources> - - <plugins> - - <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <!-- Everything but the web service tests, this is the standard test execution --> - <configuration> - <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> - <groups>${rhq.testng.includedGroups}</groups> - <systemPropertyVariables> - <embeddedDeployment>true</embeddedDeployment> - <deploymentDirectory>target/test-classes</deploymentDirectory> - <hibernate.dialect>${rhq.test.ds.hibernate-dialect}</hibernate.dialect> - <clean.db>${clean.db}</clean.db> - </systemPropertyVariables> - <argLine>-Djava.security.manager -Djava.security.policy==target/test-classes/security.policy</argLine> - <additionalClasspathElements> - <!-- The below is required for tests to run against Oracle. --> - <additionalClasspathElement>${settings.localRepository}/com/oracle/ojdbc5/${ojdbc5.version}/ojdbc5-${ojdbc5.version}.jar</additionalClasspathElement> - </additionalClasspathElements> - </configuration> - </plugin> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <executions> - - <!-- in order to get JMS to work properly in embedded test container, extract jms-rs.rar classes --> - <execution> - <id>Extract JMS classes from RAR needed for JMS tests</id> - <phase>process-classes</phase> - <configuration> - <tasks> - <unzip src="src/test/resources/jms-ra.rar" dest="target"> - <patternset> - <include name="jms-ra.jar"/> - </patternset> - </unzip> - <unzip src="target/jms-ra.jar" dest="target/test-classes"> - <patternset> - <include name="org/**"/> - </patternset> - </unzip> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - </plugins> - </build> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + </dependencies>
<profiles>
diff --git a/modules/enterprise/server/client-api/src/test/java/org/rhq/enterprise/client/security/test/EjbAccessTest.java b/modules/enterprise/server/client-api/src/test/java/org/rhq/enterprise/client/security/test/EjbAccessTest.java deleted file mode 100644 index dc1fc83..0000000 --- a/modules/enterprise/server/client-api/src/test/java/org/rhq/enterprise/client/security/test/EjbAccessTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2011 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.enterprise.client.security.test; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.SerializablePermission; -import java.security.PermissionCollection; -import java.util.Collections; - -import javax.script.ScriptEngine; -import javax.script.ScriptException; - -import org.testng.Assert; -import org.testng.annotations.Test; - -import org.rhq.bindings.SandboxedScriptEngine; -import org.rhq.bindings.ScriptEngineFactory; -import org.rhq.bindings.StandardBindings; -import org.rhq.bindings.StandardScriptPermissions; -import org.rhq.bindings.util.PackageFinder; -import org.rhq.core.domain.auth.Subject; -import org.rhq.enterprise.client.LocalClient; -import org.rhq.enterprise.server.test.AbstractEJB3Test; -import org.rhq.enterprise.server.util.LookupUtil; -import org.rhq.jndi.AllowRhqServerInternalsAccessPermission; - -/** - * - * - * @author Lukas Krejci - */ -@Test -public class EjbAccessTest extends AbstractEJB3Test { - - public void testEjbsAccessibleThroughPrivilegedCode() { - LookupUtil.getSubjectManager().getOverlord(); - } - - public void testEjbsAccessibleThroughLocalClient() throws ScriptException, IOException { - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - ScriptEngine engine = getEngine(overlord); - - engine.eval("SubjectManager.getSubjectByName('rhqadmin');"); - } - - public void testLocalEjbsInaccessibleThroughJndiLookup() throws ScriptException, IOException { - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - ScriptEngine engine = getEngine(overlord); - - try { - engine.eval("" - + "context = new javax.naming.InitialContext();\n" - + "subjectManager = context.lookup('SubjectManagerBean/local');\n" - + "subjectManager.getOverlord();"); - - Assert.fail("The script shouldn't have been able to call local SLSB method."); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - } - - public void testRemoteEjbsInaccessibleThroughJndiLookup() throws ScriptException, IOException { - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - ScriptEngine engine = getEngine(overlord); - - try { - engine.eval("" - + "context = new javax.naming.InitialContext();\n" - + "subjectManager = context.lookup('SubjectManagerBean/remote');\n" - + "subjectManager.getSubjectByName('rhqadmin');"); - - Assert.fail("The script shouldn't have been able to call remote SLSB method directly."); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - } - - public void testScriptCantUseSessionManagerMethods() throws Exception { - - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - final ScriptEngine engine = getEngine(overlord); - - class G { - private String sessionManager = "" - + "org.rhq.enterprise.server.auth.SessionManager.getInstance()."; - - public void testInvoke(String methodCall) throws ScriptException { - String code = sessionManager + methodCall; - - try { - engine.eval(code); - Assert.fail("The script shouldn't have been able to call a method on a SessionManager: " + methodCall); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - } - }; - G manager = new G(); - - manager.testInvoke("getlastAccess(0);"); - manager.testInvoke("getOverlord()"); - manager.testInvoke("getSubject(2);"); - manager.testInvoke("invalidate(0);"); - manager.testInvoke("invalidate("");"); - manager.testInvoke("put(new org.rhq.core.domain.auth.Subject());"); - manager.testInvoke("put(new org.rhq.core.domain.auth.Subject(), 0);"); - } - - public void testScriptCantObtainRawJDBCConnectionsWithoutCredentials() throws Exception { - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - ScriptEngine engine = getEngine(overlord); - - try { - engine.eval("" - + "context = new javax.naming.InitialContext();\n" - + "datasource = context.lookup('java:/RHQDS');\n" - + "con = datasource.getConnection();"); - - Assert.fail("The script shouldn't have been able to obtain the datasource from the JNDI."); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - } - - public void testScriptCantUseEntityManager() throws Exception { - Subject overlord = LookupUtil.getSubjectManager().getOverlord(); - - ScriptEngine engine = getEngine(overlord); - - try { - engine.eval("" - + "context = new javax.naming.InitialContext();\n" - + "entityManagerFactory = context.lookup('java:/RHQEntityManagerFactory');\n" - + "entityManager = entityManagerFactory.createEntityManager();\n" - + "entityManager.find(java.lang.Class.forName('org.rhq.core.domain.resource.Resource'), java.lang.Integer.valueOf('10001'));"); - - Assert.fail("The script shouldn't have been able to use the EntityManager."); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - - //try harder with manually specifying the initial context factory - try { - engine.eval("" - + "env = new java.util.Hashtable();" - + "env.put('java.naming.factory.initial', 'org.jnp.interfaces.LocalOnlyContextFactory');" - + "env.put('java.naming.factory.url.pkgs', 'org.jboss.naming:org.jnp.interfaces');" - + "context = new javax.naming.InitialContext(env);\n" - + "entityManagerFactory = context.lookup('java:/RHQEntityManagerFactory');\n" - + "entityManager = entityManagerFactory.createEntityManager();\n" - + "entityManager.find(java.lang.Class.forName('org.rhq.core.domain.resource.Resource'), java.lang.Integer.valueOf('10001'));"); - - Assert.fail("The script shouldn't have been able to use the EntityManager even using custom initial context factory."); - } catch (ScriptException e) { - checkIsDesiredSecurityException(e); - } - } - - private ScriptEngine getEngine(Subject subject) throws ScriptException, IOException { - StandardBindings bindings = new StandardBindings(new PrintWriter(System.out), new LocalClient(subject)); - ScriptEngine engine = ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File>emptyList()), bindings); - - PermissionCollection perms = new StandardScriptPermissions(); - perms.add(new SerializablePermission("enableSubclassImplementation")); - - return new SandboxedScriptEngine(engine, perms); - } - - private static void checkIsDesiredSecurityException(ScriptException e) { - String message = e.getMessage(); - String permissionTrace = AllowRhqServerInternalsAccessPermission.class.getName(); - - Assert.assertTrue(message.contains(permissionTrace), "The script exception doesn't seem to be caused by the AllowRhqServerInternalsAccessPermission security exception. " + message); - } -} diff --git a/modules/enterprise/server/client-api/src/test/resources/hibernate.properties b/modules/enterprise/server/client-api/src/test/resources/hibernate.properties deleted file mode 100644 index 1951b84..0000000 --- a/modules/enterprise/server/client-api/src/test/resources/hibernate.properties +++ /dev/null @@ -1,26 +0,0 @@ -# FOR SOME STRANGE REASON, THIS FILE NEEDS TO BE HERE FOR THE HIBERNATE TO CORRECTLY -# INITIALIZE. I DON'T KNOW WHY THE STANDARD default.persistence.properties FILE DOESN'T -# WORK IN THIS MODULE. - -hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup -#hibernate.connection.release_mode=after_statement -#hibernate.transaction.flush_before_completion=false -#hibernate.transaction.auto_close_session=false -#hibernate.query.factory_class=org.hibernate.hql.ast.ASTQueryTranslatorFactory -#hibernate.hbm2ddl.auto=create-drop -#hibernate.hbm2ddl.auto=create -hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider -# Clustered cache with TreeCache -#hibernate.cache.provider_class=org.jboss.ejb3.entity.TreeCacheProviderHook -#hibernate.treecache.mbean.object_name=jboss.cache:service=EJB3EntityTreeCache -#hibernate.dialect=org.hibernate.dialect.HSQLDialect -hibernate.jndi.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory -hibernate.jndi.java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces -hibernate.bytecode.use_reflection_optimizer=false -# I don't think this is honored, but EJB3Deployer uses it -hibernate.bytecode.provider=javassist -hibernate.jdbc.use_streams_for_binary=true -hibernate.show_sql=false -hibernate.format_sql=true -hibernate.default_batch_fetch_size=16 -hibernate.jdbc.batch_size=20 diff --git a/modules/enterprise/server/client-api/src/test/resources/jms-ra.rar b/modules/enterprise/server/client-api/src/test/resources/jms-ra.rar deleted file mode 100644 index c4807c6..0000000 Binary files a/modules/enterprise/server/client-api/src/test/resources/jms-ra.rar and /dev/null differ diff --git a/modules/enterprise/server/client-api/src/test/resources/security.policy b/modules/enterprise/server/client-api/src/test/resources/security.policy deleted file mode 100644 index 8860b47..0000000 --- a/modules/enterprise/server/client-api/src/test/resources/security.policy +++ /dev/null @@ -1,10 +0,0 @@ -// We need the SecurityManager installed to enable sandboxing of CLI scripts -// but we don't define any other security measures on the RHQ server itself. -// -// Granting all permissions allows us to run the RHQ server as if no security -// manager was in place (which is assumed by default by JBoss AS) but be able -// to use it when we need it for our own purposes. - -grant { - permission java.security.AllPermission; -}; diff --git a/modules/enterprise/server/itests/pom.xml b/modules/enterprise/server/itests/pom.xml index 6898621..653ef99 100644 --- a/modules/enterprise/server/itests/pom.xml +++ b/modules/enterprise/server/itests/pom.xml @@ -58,6 +58,7 @@ <groupId>org.rhq</groupId> <artifactId>rhq-container-lib</artifactId> <version>${project.version}</version> + <scope>test</scope> </dependency>
<dependency> @@ -84,6 +85,32 @@ </dependency>
<dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-script-bindings</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-server-client-api</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> <groupId>org.rhq.helpers</groupId> <artifactId>perftest-support</artifactId> <version>${project.version}</version> @@ -232,6 +259,7 @@ <artifactId>resteasy-jaxrs</artifactId> <version>${resteasy.version}</version> </dependency> + </dependencies>
<build> @@ -270,6 +298,23 @@ </execution> </executions> </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <!-- Everything but the web service tests, this is the standard test execution --> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <groups>${rhq.testng.includedGroups}</groups> + <systemPropertyVariables> + <embeddedDeployment>true</embeddedDeployment> + <deploymentDirectory>target/test-classes</deploymentDirectory> + </systemPropertyVariables> + <argLine>-Djava.security.manager -Djava.security.policy==${basedir}/target/test-classes/security.policy</argLine> + <additionalClasspathElements> + <!-- The below is required for tests to run against Oracle. --> + <additionalClasspathElement>${settings.localRepository}/com/oracle/ojdbc5/${ojdbc5.version}/ojdbc5-${ojdbc5.version}.jar</additionalClasspathElement> + </additionalClasspathElements> + </configuration> + </plugin> </plugins> </build> </project> diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/client/security/test/JndiAccessTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/client/security/test/JndiAccessTest.java new file mode 100644 index 0000000..ae848a8 --- /dev/null +++ b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/client/security/test/JndiAccessTest.java @@ -0,0 +1,198 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2011 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package org.rhq.enterprise.client.security.test; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.SerializablePermission; +import java.security.PermissionCollection; +import java.util.Collections; + +import javax.script.ScriptEngine; +import javax.script.ScriptException; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.rhq.bindings.SandboxedScriptEngine; +import org.rhq.bindings.ScriptEngineFactory; +import org.rhq.bindings.StandardBindings; +import org.rhq.bindings.StandardScriptPermissions; +import org.rhq.bindings.util.PackageFinder; +import org.rhq.core.domain.auth.Subject; +import org.rhq.enterprise.client.LocalClient; +import org.rhq.enterprise.server.test.AbstractEJB3Test; +import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.jndi.AllowRhqServerInternalsAccessPermission; + +/** + * + * + * @author Lukas Krejci + */ +@Test +public class JndiAccessTest extends AbstractEJB3Test { + + public void testEjbsAccessibleThroughPrivilegedCode() { + LookupUtil.getSubjectManager().getOverlord(); + } + + public void testEjbsAccessibleThroughLocalClient() throws ScriptException, IOException { + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + ScriptEngine engine = getEngine(overlord); + + engine.eval("SubjectManager.getSubjectByName('rhqadmin');"); + } + + public void testLocalEjbsInaccessibleThroughJndiLookup() throws ScriptException, IOException { + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + ScriptEngine engine = getEngine(overlord); + + try { + engine.eval("" + + "context = new javax.naming.InitialContext();\n" + + "subjectManager = context.lookup('SubjectManagerBean/local');\n" + + "subjectManager.getOverlord();"); + + Assert.fail("The script shouldn't have been able to call local SLSB method."); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + } + + public void testRemoteEjbsInaccessibleThroughJndiLookup() throws ScriptException, IOException { + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + ScriptEngine engine = getEngine(overlord); + + try { + engine.eval("" + + "context = new javax.naming.InitialContext();\n" + + "subjectManager = context.lookup('SubjectManagerBean/remote');\n" + + "subjectManager.getSubjectByName('rhqadmin');"); + + Assert.fail("The script shouldn't have been able to call remote SLSB method directly."); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + } + + public void testScriptCantUseSessionManagerMethods() throws Exception { + + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + final ScriptEngine engine = getEngine(overlord); + + class G { + private String sessionManager = "" + + "org.rhq.enterprise.server.auth.SessionManager.getInstance()."; + + public void testInvoke(String methodCall) throws ScriptException { + String code = sessionManager + methodCall; + + try { + engine.eval(code); + Assert.fail("The script shouldn't have been able to call a method on a SessionManager: " + methodCall); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + } + }; + G manager = new G(); + + manager.testInvoke("getlastAccess(0);"); + manager.testInvoke("getOverlord()"); + manager.testInvoke("getSubject(2);"); + manager.testInvoke("invalidate(0);"); + manager.testInvoke("invalidate("");"); + manager.testInvoke("put(new org.rhq.core.domain.auth.Subject());"); + manager.testInvoke("put(new org.rhq.core.domain.auth.Subject(), 0);"); + } + + public void testScriptCantObtainRawJDBCConnectionsWithoutCredentials() throws Exception { + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + ScriptEngine engine = getEngine(overlord); + + try { + engine.eval("" + + "context = new javax.naming.InitialContext();\n" + + "datasource = context.lookup('java:/RHQDS');\n" + + "con = datasource.getConnection();"); + + Assert.fail("The script shouldn't have been able to obtain the datasource from the JNDI."); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + } + + public void testScriptCantUseEntityManager() throws Exception { + Subject overlord = LookupUtil.getSubjectManager().getOverlord(); + + ScriptEngine engine = getEngine(overlord); + + try { + engine.eval("" + + "context = new javax.naming.InitialContext();\n" + + "entityManagerFactory = context.lookup('java:/RHQEntityManagerFactory');\n" + + "entityManager = entityManagerFactory.createEntityManager();\n" + + "entityManager.find(java.lang.Class.forName('org.rhq.core.domain.resource.Resource'), java.lang.Integer.valueOf('10001'));"); + + Assert.fail("The script shouldn't have been able to use the EntityManager."); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + + //try harder with manually specifying the initial context factory + try { + engine.eval("" + + "env = new java.util.Hashtable();" + + "env.put('java.naming.factory.initial', 'org.jnp.interfaces.LocalOnlyContextFactory');" + + "env.put('java.naming.factory.url.pkgs', 'org.jboss.naming:org.jnp.interfaces');" + + "context = new javax.naming.InitialContext(env);\n" + + "entityManagerFactory = context.lookup('java:/RHQEntityManagerFactory');\n" + + "entityManager = entityManagerFactory.createEntityManager();\n" + + "entityManager.find(java.lang.Class.forName('org.rhq.core.domain.resource.Resource'), java.lang.Integer.valueOf('10001'));"); + + Assert.fail("The script shouldn't have been able to use the EntityManager even using custom initial context factory."); + } catch (ScriptException e) { + checkIsDesiredSecurityException(e); + } + } + + private ScriptEngine getEngine(Subject subject) throws ScriptException, IOException { + StandardBindings bindings = new StandardBindings(new PrintWriter(System.out), new LocalClient(subject)); + ScriptEngine engine = ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File>emptyList()), bindings); + + PermissionCollection perms = new StandardScriptPermissions(); + perms.add(new SerializablePermission("enableSubclassImplementation")); + + return new SandboxedScriptEngine(engine, perms); + } + + private static void checkIsDesiredSecurityException(ScriptException e) { + String message = e.getMessage(); + String permissionTrace = AllowRhqServerInternalsAccessPermission.class.getName(); + + Assert.assertTrue(message.contains(permissionTrace), "The script exception doesn't seem to be caused by the AllowRhqServerInternalsAccessPermission security exception. " + message); + } +} diff --git a/modules/enterprise/server/itests/src/test/resources/embedded-jboss-beans.xml b/modules/enterprise/server/itests/src/test/resources/embedded-jboss-beans.xml index 05edefa..85e2fb3 100644 --- a/modules/enterprise/server/itests/src/test/resources/embedded-jboss-beans.xml +++ b/modules/enterprise/server/itests/src/test/resources/embedded-jboss-beans.xml @@ -4,6 +4,14 @@ xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0">
+ <!-- This installs a custom initial context factory builder into the JVM + that will ensure that all the default InitialContexts are going to check + for the permission to access the RHQ internals. --> + <bean class="org.rhq.jndi.mbean.AccessCheckingInitialContextFactoryBuilderInstaller" + name="AccessCheckingInitialContextFactoryBuilderInstaller"> + </bean> + + <bean name="Naming" class="org.jnp.server.SingletonNamingServer"/>
<bean name="InitialContextProperties" class="java.util.Hashtable"> @@ -20,7 +28,7 @@ </entry> </map> </parameter> - </constructor> + </constructor> </bean>
<bean name="java:comp/Initializer" class="org.jboss.ejb3.embedded.JavaCompInitializer"> diff --git a/modules/enterprise/server/itests/src/test/resources/security.policy b/modules/enterprise/server/itests/src/test/resources/security.policy new file mode 100644 index 0000000..8860b47 --- /dev/null +++ b/modules/enterprise/server/itests/src/test/resources/security.policy @@ -0,0 +1,10 @@ +// We need the SecurityManager installed to enable sandboxing of CLI scripts +// but we don't define any other security measures on the RHQ server itself. +// +// Granting all permissions allows us to run the RHQ server as if no security +// manager was in place (which is assumed by default by JBoss AS) but be able +// to use it when we need it for our own purposes. + +grant { + permission java.security.AllPermission; +};
rhq-commits@lists.fedorahosted.org