169N/A/*
5266N/A * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
169N/A
0N/A/* @test
0N/A * @bug 4179055
0N/A * @summary Some java apps need to have access to read "accessClassInPackage.sun.rmi.server"
0N/A * @author Laird Dornin
0N/A *
0N/A * @library ../../../testlibrary
5551N/A * @build TestLibrary RMID ActivationLibrary
5551N/A * CanCreateStubs StubClassesPermitted_Stub
0N/A * @run main/othervm/policy=security.policy/secure=java.lang.SecurityManager/timeout=240 StubClassesPermitted
0N/A */
0N/A
0N/Aimport java.io.*;
0N/Aimport java.rmi.*;
0N/Aimport java.rmi.server.*;
0N/Aimport java.rmi.registry.Registry;
0N/Aimport java.rmi.activation.*;
0N/Aimport java.security.CodeSource;
0N/Aimport java.util.Properties;
0N/Aimport java.util.StringTokenizer;
0N/A
0N/A/**
0N/A * The RMI activation system needs to explicitly allow itself to
0N/A * create the following sun.* classes on behalf of code that runs with
0N/A * user privileges and needs to make use of RMI activation:
0N/A *
0N/A * sun.rmi.server.Activation$ActivationMonitorImpl_Stub
0N/A * sun.rmi.server.Activation$ActivationSystemImpl_Stub
0N/A * sun.rmi.registry.RegistryImpl_Stub
0N/A *
0N/A * The test causes the activation system to need to create each of
0N/A * these classes in turn. The test will fail if the activation system
169N/A * does not allow these classes to be created.
0N/A */
0N/Apublic class StubClassesPermitted
0N/A extends Activatable implements Runnable, CanCreateStubs
0N/A{
0N/A public static boolean sameGroup = false;
5266N/A private static int registryPort = -1;
0N/A private static CanCreateStubs canCreateStubs = null;
0N/A private static Registry registry = null;
0N/A
169N/A public static void main(String args[]) {
0N/A
169N/A sameGroup = true;
169N/A
169N/A RMID rmid = null;
0N/A
169N/A System.err.println("\nRegression test for bug/rfe 4179055\n");
0N/A
169N/A try {
169N/A TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
169N/A
5266N/A registry = TestLibrary.createRegistryOnUnusedPort();
5266N/A registryPort = TestLibrary.getRegistryPort(registry);
0N/A
169N/A // must run with java.lang.SecurityManager or the test
169N/A // result will be nullified if running with a build where
169N/A // 4180392 has not been fixed.
169N/A String smClassName =
169N/A System.getSecurityManager().getClass().getName();
169N/A if (!smClassName.equals("java.lang.SecurityManager")) {
169N/A TestLibrary.bomb("Test must run with java.lang.SecurityManager");
169N/A }
0N/A
169N/A // start an rmid.
169N/A RMID.removeLog();
169N/A rmid = RMID.createRMID();
169N/A rmid.start();
0N/A
169N/A //rmid.addOptions(new String[] {"-C-Djava.rmi.server.logCalls=true"});
0N/A
169N/A // Ensure that activation groups run with the correct
169N/A // security manager.
169N/A //
169N/A Properties p = new Properties();
169N/A p.put("java.security.policy",
169N/A TestParams.defaultGroupPolicy);
169N/A p.put("java.security.manager",
169N/A "java.lang.SecurityManager");
0N/A
169N/A // This action causes the following classes to be created
169N/A // in this VM (RMI must permit the creation of these classes):
169N/A //
169N/A // sun.rmi.server.Activation$ActivationSystemImpl_Stub
169N/A // sun.rmi.server.Activation$ActivationMonitorImpl_Stub
169N/A //
169N/A System.err.println("Create activation group, in a new VM");
169N/A ActivationGroupDesc groupDesc =
169N/A new ActivationGroupDesc(p, null);
169N/A ActivationSystem system = ActivationGroup.getSystem();
169N/A ActivationGroupID groupID = system.registerGroup(groupDesc);
169N/A
169N/A System.err.println("register activatable");
169N/A // Fix for: 4271615: make sure activation group runs in a new VM
169N/A ActivationDesc desc = new ActivationDesc
169N/A (groupID, "StubClassesPermitted", null, null);
169N/A canCreateStubs = (CanCreateStubs) Activatable.register(desc);
0N/A
169N/A // ensure registry stub can be passed in a remote call
169N/A System.err.println("getting the registry");
169N/A registry = canCreateStubs.getRegistry();
169N/A
169N/A // make sure a client cant load just any sun.* class, just
169N/A // as a sanity check, try to create a class we are not
169N/A // allowed to access but which was passed in a remote call
169N/A try {
169N/A System.err.println("accessing forbidden class");
169N/A Object secureRandom = canCreateStubs.getForbiddenClass();
0N/A
169N/A TestLibrary.bomb("test allowed to access forbidden class," +
169N/A " sun.security.provider.SecureRandom");
169N/A } catch (java.security.AccessControlException e) {
0N/A
169N/A // Make sure we received a *local* AccessControlException
169N/A ByteArrayOutputStream bout = new ByteArrayOutputStream();
169N/A PrintStream ps = new PrintStream(bout);
169N/A e.printStackTrace(ps);
169N/A ps.flush();
169N/A String trace = new String(bout.toByteArray());
169N/A if ((trace.indexOf("exceptionReceivedFromServer") >= 0) ||
169N/A trace.equals(""))
0N/A {
169N/A throw e;
169N/A }
169N/A System.err.println("received expected local access control exception");
169N/A }
0N/A
169N/A // make sure that an ActivationGroupID can be passed in a
169N/A // remote call; this is slightly more inclusive than
169N/A // just passing a reference to the activation system
169N/A System.err.println("returning group desc");
169N/A canCreateStubs.returnGroupID();
169N/A
169N/A // Clean up object
169N/A System.err.println
169N/A ("Deactivate object via method call");
169N/A canCreateStubs.shutdown();
169N/A
169N/A System.err.println
169N/A ("\nsuccess: StubClassesPermitted test passed ");
0N/A
169N/A } catch (Exception e) {
169N/A TestLibrary.bomb("\nfailure: unexpected exception ", e);
169N/A } finally {
169N/A try {
169N/A Thread.sleep(4000);
169N/A } catch (InterruptedException e) {
169N/A }
169N/A
169N/A canCreateStubs = null;
169N/A ActivationLibrary.rmidCleanup(rmid);
169N/A System.err.println("rmid shut down");
169N/A }
0N/A }
169N/A
0N/A static ActivationGroupID GroupID = null;
0N/A
0N/A /**
169N/A * implementation of CanCreateStubs
0N/A */
0N/A public StubClassesPermitted
169N/A (ActivationID id, MarshalledObject mo) throws RemoteException
0N/A {
169N/A // register/export anonymously
169N/A super(id, 0);
0N/A
169N/A // obtain reference to the test registry
169N/A registry = java.rmi.registry.LocateRegistry.
5266N/A getRegistry(registryPort);
0N/A }
169N/A
0N/A /**
0N/A * Spawns a thread to deactivate the object.
0N/A */
0N/A public void shutdown() throws Exception {
169N/A (new Thread(this,"StubClassesPermitted")).start();
0N/A }
0N/A
0N/A /**
0N/A * Thread to deactivate object. First attempts to make object
0N/A * inactive (via the inactive method). If that fails (the
0N/A * object may still have pending/executing calls), then
0N/A * unexport the object forcibly.
0N/A */
0N/A public void run() {
169N/A ActivationLibrary.deactivate(this, getID());
0N/A }
0N/A
0N/A /**
0N/A * Return a reference to the RMI registry, to make sure that
0N/A * the stub for it can be deserialized in the test client VM.
0N/A */
0N/A public Registry getRegistry() throws RemoteException {
169N/A if (sameGroup) {
169N/A System.out.println("in same group");
169N/A } else {
169N/A System.out.println("not in same group");
169N/A }
169N/A return registry;
0N/A }
0N/A
0N/A /**
0N/A * Remote call to create and return a random serializable sun.*
0N/A * class, the test should get a local security exception when
0N/A * trying to create the class. Ensure that not all sun.* classes
0N/A * can be resolved in a remote call.
0N/A */
0N/A public Object getForbiddenClass() throws RemoteException {
169N/A System.err.println("creating sun class");
169N/A return new sun.security.provider.SecureRandom();
0N/A }
0N/A
0N/A /**
0N/A * Ensures that an activation group id can be passed in a remote
0N/A * call (class may contain a remote reference to the activation
0N/A * system implementation).
0N/A */
0N/A public ActivationGroupID returnGroupID() throws RemoteException {
169N/A return ActivationGroup.currentGroupID();
0N/A }
0N/A}