ccb64b56b2
Reviewed-by: weijun
543 lines
18 KiB
Java
543 lines
18 KiB
Java
/*
|
|
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code 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
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.security.AccessControlContext;
|
|
import java.security.AccessControlException;
|
|
import java.security.AccessController;
|
|
import java.security.PrivilegedAction;
|
|
import java.security.PrivilegedActionException;
|
|
import java.security.PrivilegedExceptionAction;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.jar.JarEntry;
|
|
import java.util.jar.JarOutputStream;
|
|
import java.util.jar.Manifest;
|
|
import javax.security.auth.Subject;
|
|
import javax.security.auth.x500.X500Principal;
|
|
import jdk.testlibrary.ProcessTools;
|
|
|
|
/**
|
|
* @test
|
|
* @bug 8048147
|
|
* @summary Check if proper AccessControlException is thrown
|
|
* in case of nested Subject.doAs() invocations
|
|
* when one of protection domains doesn't have permissions
|
|
*
|
|
* @library /lib/testlibrary
|
|
*
|
|
* @run main NestedActions jar NestedActionsACE.jar
|
|
* NestedActionsACE.class Utils.class
|
|
* @run main NestedActions jar NestedActionsPAE.jar
|
|
* NestedActionsPAE.class Utils.class
|
|
* @run main NestedActions jar NestedActionsOnePrincipal.jar
|
|
* NestedActionsOnePrincipal.class Utils.class
|
|
* @run main NestedActions jar NestedActionsTwoPrincipals.jar
|
|
* NestedActionsTwoPrincipals.class Utils.class
|
|
* @run main NestedActions jar WriteToFileAction.jar
|
|
* WriteToFileAction.class
|
|
* @run main NestedActions jar WriteToFileNegativeAction.jar
|
|
* WriteToFileNegativeAction.class
|
|
* @run main NestedActions jar WriteToFileExceptionAction.jar
|
|
* WriteToFileExceptionAction.class
|
|
* @run main NestedActions jar ReadFromFileAction.jar
|
|
* ReadFromFileAction.class
|
|
* @run main NestedActions jar ReadFromFileNegativeAction.jar
|
|
* ReadFromFileNegativeAction.class
|
|
* @run main NestedActions jar ReadFromFileExceptionAction.jar
|
|
* ReadFromFileExceptionAction.class
|
|
* @run main NestedActions jar ReadPropertyAction.jar
|
|
* ReadPropertyAction.class
|
|
* @run main NestedActions jar ReadPropertyNegativeAction.jar
|
|
* ReadPropertyNegativeAction.class
|
|
* @run main NestedActions jar ReadPropertyExceptionAction.jar
|
|
* ReadPropertyExceptionAction.class ReadPropertyException.class
|
|
*
|
|
* @run main NestedActions NestedActionsACE policy.expect.ace
|
|
* NestedActionsACE.jar WriteToFileNegativeAction.jar
|
|
* ReadFromFileNegativeAction.jar ReadPropertyNegativeAction.jar
|
|
* @run main NestedActions NestedActionsPAE policy.expect.pae
|
|
* NestedActionsPAE.jar WriteToFileExceptionAction.jar
|
|
* ReadFromFileExceptionAction.jar ReadPropertyExceptionAction.jar
|
|
* @run main NestedActions NestedActionsOnePrincipal policy.one.principal
|
|
* NestedActionsOnePrincipal.jar WriteToFileAction.jar
|
|
* ReadFromFileAction.jar ReadPropertyAction.jar
|
|
* @run main NestedActions NestedActionsTwoPrincipals policy.two.principals
|
|
* NestedActionsTwoPrincipals.jar WriteToFileAction.jar
|
|
* ReadFromFileAction.jar ReadPropertyAction.jar
|
|
*/
|
|
public class NestedActions {
|
|
|
|
static final String file = "NestedActions.tmp";
|
|
static final String PS = System.getProperty("path.separator");
|
|
static final String FS = System.getProperty("file.separator");
|
|
static final String TEST_CLASSES = System.getProperty("test.classes");
|
|
static final String TEST_SOURCES = System.getProperty("test.src");
|
|
static final String JAVA_OPTS = System.getProperty("test.java.opts");
|
|
static final String JAVA = System.getProperty("java.home")
|
|
+ FS + "bin" + FS + "java";
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
if (args.length > 0) {
|
|
if ("jar".equals(args[0]) && args.length > 2) {
|
|
createJar(args[1],
|
|
Arrays.copyOfRange(args, 2, args.length));
|
|
} else {
|
|
runJava(args);
|
|
}
|
|
} else {
|
|
throw new RuntimeException("Wrong parameters");
|
|
}
|
|
}
|
|
|
|
static void createJar(String dest, String... files) throws IOException {
|
|
System.out.println("Create " + dest + " with the following content:");
|
|
try (JarOutputStream jos = new JarOutputStream(
|
|
new FileOutputStream(dest), new Manifest())) {
|
|
for (String file : files) {
|
|
System.out.println(" " + file);
|
|
jos.putNextEntry(new JarEntry(file));
|
|
try (FileInputStream fis = new FileInputStream(
|
|
TEST_CLASSES + FS + file)) {
|
|
fis.transferTo(jos);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void runJava(String[] args) {
|
|
if (args == null || args.length < 3) {
|
|
throw new IllegalArgumentException("wrong parameters");
|
|
}
|
|
|
|
List<String> cmds = new ArrayList<>();
|
|
cmds.add(JAVA);
|
|
StringBuilder sb = new StringBuilder();
|
|
cmds.add("-classpath");
|
|
for (int i=2; i<args.length; i++) {
|
|
sb.append(args[i]).append(PS);
|
|
}
|
|
cmds.add(sb.toString());
|
|
if (JAVA_OPTS != null && !JAVA_OPTS.isEmpty()) {
|
|
Collections.addAll(cmds, JAVA_OPTS.trim().split("\\s+"));
|
|
}
|
|
cmds.add("-Djava.security.manager");
|
|
cmds.add("-Djava.security.policy=" + TEST_SOURCES + FS + args[1]);
|
|
cmds.add(args[0]);
|
|
try {
|
|
ProcessTools.executeCommand(cmds.toArray(new String[cmds.size()]))
|
|
.shouldHaveExitValue(0);
|
|
} catch (Throwable e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for nested Subject.doAs() invocation:
|
|
*
|
|
* WriteToFileAction (CN=Duke principal) ->
|
|
* ReadFromFileAction (CN=Duke principal) ->
|
|
* ReadPropertyAction (CN=Duke principal)
|
|
*
|
|
* The test expects AccessControllException.
|
|
*/
|
|
class NestedActionsACE {
|
|
|
|
public static void main(String args[]) {
|
|
Subject subject = new Subject();
|
|
subject.getPrincipals().add(new X500Principal("CN=Duke"));
|
|
WriteToFileNegativeAction writeToFile
|
|
= new WriteToFileNegativeAction(NestedActions.file);
|
|
Subject.doAs(subject, writeToFile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for nested Subject.doAs() invocation:
|
|
*
|
|
* WriteToFileAction (CN=Duke principal) ->
|
|
* ReadFromFileAction (CN=Duke principal) ->
|
|
* ReadPropertyAction (CN=Duke principal)
|
|
*
|
|
* The test expects PrivilegedActionException
|
|
* that caused by AccessControlEception.
|
|
*/
|
|
class NestedActionsPAE {
|
|
|
|
public static void main(String args[]) {
|
|
Subject subject = new Subject();
|
|
subject.getPrincipals().add(new X500Principal("CN=Duke"));
|
|
try {
|
|
WriteToFileExceptionAction writeToFile =
|
|
new WriteToFileExceptionAction(NestedActions.file);
|
|
Subject.doAs(subject, writeToFile);
|
|
throw new RuntimeException(
|
|
"Test failed: no PrivilegedActionException thrown");
|
|
} catch (PrivilegedActionException pae) {
|
|
System.out.println(
|
|
"PrivilegedActionException thrown as expected: "
|
|
+ pae);
|
|
|
|
// check if AccessControlException caused PrivilegedActionException
|
|
Throwable exception = pae.getException();
|
|
do {
|
|
if (!(exception instanceof PrivilegedActionException)) {
|
|
break;
|
|
}
|
|
exception = ((PrivilegedActionException) exception).
|
|
getException();
|
|
} while (true);
|
|
|
|
if (!(exception instanceof ReadPropertyException)) {
|
|
throw new RuntimeException(
|
|
"Test failed: PrivilegedActionException "
|
|
+ "was not caused by ReadPropertyException");
|
|
}
|
|
|
|
exception = exception.getCause();
|
|
if (!(exception instanceof AccessControlException)) {
|
|
throw new RuntimeException(
|
|
"Test failed: PrivilegedActionException "
|
|
+ "was not caused by ReadPropertyException");
|
|
}
|
|
|
|
System.out.println(
|
|
"Test passed: PrivilegedActionException "
|
|
+ "was caused by AccessControlException");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for nested Subject.doAs() invocation:
|
|
*
|
|
* WriteToFileAction (CN=Duke principal) ->
|
|
* ReadFromFileAction (CN=Duke principal) ->
|
|
* ReadPropertyAction (CN=Duke principal)
|
|
*/
|
|
class NestedActionsOnePrincipal {
|
|
|
|
public static void main(String args[]) {
|
|
Subject subject = new Subject();
|
|
subject.getPrincipals().add(new X500Principal("CN=Duke"));
|
|
WriteToFileAction writeToFile =
|
|
new WriteToFileAction(NestedActions.file);
|
|
Subject.doAs(subject, writeToFile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for nested Subject.doAs() invocation:
|
|
*
|
|
* WriteToFileAction (CN=Duke principal) ->
|
|
* ReadFromFileAction (CN=Duke principal) ->
|
|
* ReadPropertyAction (CN=Java principal)
|
|
*/
|
|
class NestedActionsTwoPrincipals {
|
|
|
|
public static void main(String args[]) {
|
|
Subject subject = new Subject();
|
|
subject.getPrincipals().add(new X500Principal("CN=Duke"));
|
|
Subject anotherSubject = new Subject();
|
|
anotherSubject.getPrincipals().add(new X500Principal("CN=Java"));
|
|
ReadFromFileAction readFromFile
|
|
= new ReadFromFileAction(NestedActions.file, anotherSubject);
|
|
WriteToFileAction writeToFile
|
|
= new WriteToFileAction(NestedActions.file, readFromFile);
|
|
Subject.doAs(subject, writeToFile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class.
|
|
*/
|
|
class Utils {
|
|
|
|
static void readFile(String filename) {
|
|
System.out.println("ReadFromFileAction: try to read " + filename);
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
System.out.println("principals = " + subject.getPrincipals());
|
|
try (FileInputStream fis = new FileInputStream(filename)) {
|
|
// do nothing
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Unexpected IOException", e);
|
|
}
|
|
}
|
|
|
|
static void writeFile(String filename) {
|
|
System.out.println("WriteToFileAction: try to write to " + filename);
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
System.out.println("principals = " + subject.getPrincipals());
|
|
try (BufferedOutputStream bos = new BufferedOutputStream(
|
|
new FileOutputStream(filename))) {
|
|
bos.write(0);
|
|
bos.flush();
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Unexpected IOException", e);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class WriteToFileAction implements PrivilegedAction {
|
|
|
|
private final String filename;
|
|
private final PrivilegedAction nextAction;
|
|
|
|
WriteToFileAction(String filename, PrivilegedAction nextAction) {
|
|
this.filename = filename;
|
|
this.nextAction = nextAction;
|
|
}
|
|
|
|
WriteToFileAction(String filename) {
|
|
this(filename, new ReadFromFileAction(filename));
|
|
}
|
|
|
|
@Override
|
|
public Object run() {
|
|
Utils.writeFile(filename);
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
return Subject.doAs(subject, nextAction);
|
|
}
|
|
|
|
}
|
|
|
|
class ReadFromFileAction implements PrivilegedAction {
|
|
|
|
private final String filename;
|
|
private final Subject anotherSubject;
|
|
|
|
ReadFromFileAction(String filename) {
|
|
this(filename, null);
|
|
}
|
|
|
|
ReadFromFileAction(String filename, Subject anotherSubject) {
|
|
this.filename = filename;
|
|
this.anotherSubject = anotherSubject;
|
|
}
|
|
|
|
@Override
|
|
public Object run() {
|
|
Utils.readFile(filename);
|
|
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
ReadPropertyAction readProperty = new ReadPropertyAction();
|
|
if (anotherSubject != null) {
|
|
return Subject.doAs(anotherSubject, readProperty);
|
|
} else {
|
|
return Subject.doAs(subject, readProperty);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class ReadPropertyAction implements PrivilegedAction {
|
|
|
|
@Override
|
|
public java.lang.Object run() {
|
|
System.out.println("ReadPropertyAction: "
|
|
+ "try to read 'java.class.path' property");
|
|
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject s = Subject.getSubject(acc);
|
|
System.out.println("principals = " + s.getPrincipals());
|
|
System.out.println("java.class.path = "
|
|
+ System.getProperty("java.class.path"));
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
class WriteToFileNegativeAction implements PrivilegedAction {
|
|
|
|
private final String filename;
|
|
|
|
public WriteToFileNegativeAction(String filename) {
|
|
this.filename = filename;
|
|
}
|
|
|
|
@Override
|
|
public Object run() {
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
System.out.println("principals = " + subject.getPrincipals());
|
|
|
|
try {
|
|
Utils.writeFile(filename);
|
|
new File(filename).delete();
|
|
throw new RuntimeException(
|
|
"Test failed: no AccessControlException thrown");
|
|
} catch (AccessControlException ace) {
|
|
System.out.println(
|
|
"AccessControlException thrown as expected: "
|
|
+ ace.getMessage());
|
|
}
|
|
|
|
ReadFromFileNegativeAction readFromFile
|
|
= new ReadFromFileNegativeAction(filename);
|
|
return Subject.doAs(subject, readFromFile);
|
|
}
|
|
|
|
}
|
|
|
|
class ReadFromFileNegativeAction implements PrivilegedAction {
|
|
|
|
private final String filename;
|
|
|
|
public ReadFromFileNegativeAction(String filename) {
|
|
this.filename = filename;
|
|
}
|
|
|
|
@Override
|
|
public Object run() {
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
System.out.println("principals = " + subject.getPrincipals());
|
|
|
|
try {
|
|
Utils.readFile(filename);
|
|
throw new RuntimeException(
|
|
"Test failed: no AccessControlException thrown");
|
|
} catch (AccessControlException ace) {
|
|
System.out.println(
|
|
"AccessControlException thrown as expected: "
|
|
+ ace.getMessage());
|
|
}
|
|
|
|
ReadPropertyNegativeAction readProperty =
|
|
new ReadPropertyNegativeAction();
|
|
return Subject.doAs(subject, readProperty);
|
|
}
|
|
|
|
}
|
|
|
|
class ReadPropertyNegativeAction implements PrivilegedAction {
|
|
|
|
@Override
|
|
public java.lang.Object run() {
|
|
System.out.println("Try to read 'java.class.path' property");
|
|
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject s = Subject.getSubject(acc);
|
|
System.out.println("principals = " + s.getPrincipals());
|
|
|
|
try {
|
|
System.out.println("java.class.path = "
|
|
+ System.getProperty("java.class.path"));
|
|
throw new RuntimeException(
|
|
"Test failed: no AccessControlException thrown");
|
|
} catch (AccessControlException ace) {
|
|
System.out.println(
|
|
"AccessControlException thrown as expected: "
|
|
+ ace.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
class WriteToFileExceptionAction implements PrivilegedExceptionAction {
|
|
|
|
private final String filename;
|
|
|
|
WriteToFileExceptionAction(String filename) {
|
|
this.filename = filename;
|
|
}
|
|
|
|
@Override
|
|
public Object run() throws Exception {
|
|
Utils.writeFile(filename);
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
ReadFromFileExceptionAction readFromFile =
|
|
new ReadFromFileExceptionAction(filename);
|
|
return Subject.doAs(subject, readFromFile);
|
|
}
|
|
|
|
}
|
|
|
|
class ReadFromFileExceptionAction implements PrivilegedExceptionAction {
|
|
|
|
private final String filename;
|
|
|
|
ReadFromFileExceptionAction(String filename) {
|
|
this.filename = filename;
|
|
}
|
|
|
|
@Override
|
|
public Object run() throws Exception {
|
|
Utils.readFile(filename);
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject subject = Subject.getSubject(acc);
|
|
ReadPropertyExceptionAction readProperty =
|
|
new ReadPropertyExceptionAction();
|
|
return Subject.doAs(subject, readProperty);
|
|
}
|
|
|
|
}
|
|
|
|
class ReadPropertyExceptionAction implements PrivilegedExceptionAction {
|
|
|
|
@Override
|
|
public java.lang.Object run() throws Exception {
|
|
System.out.println("Try to read 'java.class.path' property");
|
|
|
|
AccessControlContext acc = AccessController.getContext();
|
|
Subject s = Subject.getSubject(acc);
|
|
System.out.println("principals = " + s.getPrincipals());
|
|
|
|
try {
|
|
System.out.println("java.class.path = "
|
|
+ System.getProperty("java.class.path"));
|
|
throw new RuntimeException(
|
|
"Test failed: no AccessControlException thrown");
|
|
} catch (AccessControlException ace) {
|
|
System.out.println(
|
|
"AccessControlException thrown as expected: "
|
|
+ ace.getMessage());
|
|
throw new ReadPropertyException(ace);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class ReadPropertyException extends Exception {
|
|
|
|
ReadPropertyException(Throwable cause) {
|
|
super(cause);
|
|
}
|
|
}
|