1 /*
   2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8003881
  27  * @summary tests DoPrivileged action (implemented as lambda expressions) by
  28  * inserting them into the BootClassPath.
  29  * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java
  30  * @run main/othervm LambdaAccessControlDoPrivilegedTest
  31  */
  32 import java.io.BufferedReader;
  33 import java.io.File;
  34 import java.io.IOException;
  35 import java.io.InputStreamReader;
  36 import java.io.PrintWriter;
  37 import java.io.StringWriter;
  38 import java.nio.charset.Charset;
  39 import java.nio.file.Files;
  40 import java.util.ArrayList;
  41 import java.util.List;
  42 import java.util.Map;
  43 
  44 public class LambdaAccessControlDoPrivilegedTest extends LUtils {
  45     public static void main(String... args) {
  46         final List<String> scratch = new ArrayList();
  47         scratch.clear();
  48         scratch.add("import java.security.*;");
  49         scratch.add("public class DoPriv {");
  50         scratch.add("public static void main(String... args) {");
  51         scratch.add("String prop = AccessController.doPrivileged((PrivilegedAction<String>) () -> {");
  52         scratch.add("return System.getProperty(\"user.home\");");
  53         scratch.add("});");
  54         scratch.add("}");
  55         scratch.add("}");
  56         File doprivJava = new File("DoPriv.java");
  57         File doprivClass = getClassFile(doprivJava);
  58         createFile(doprivJava, scratch);
  59 
  60         scratch.clear();
  61         scratch.add("public class Bar {");
  62         scratch.add("public static void main(String... args) {");
  63         scratch.add("System.out.println(\"sun.boot.class.path\" + \"=\" +");
  64         scratch.add("    System.getProperty(\"sun.boot.class.path\", \"\"));");
  65         scratch.add("System.setSecurityManager(new SecurityManager());");
  66         scratch.add("DoPriv.main();");
  67         scratch.add("}");
  68         scratch.add("}");
  69 
  70         File barJava = new File("Bar.java");
  71         File barClass = getClassFile(barJava);
  72         createFile(barJava, scratch);
  73 
  74         String[] javacArgs = {barJava.getName(), doprivJava.getName()};
  75         compile(javacArgs);
  76         File jarFile = new File("foo.jar");
  77         String[] jargs = {"cvf", jarFile.getName(), doprivClass.getName()};
  78         jarTool.run(jargs);
  79         doprivJava.delete();
  80         doprivClass.delete();
  81         TestResult tr = doExec(JAVA_CMD.getAbsolutePath(),
  82                                "-Xbootclasspath/p:foo.jar",
  83                                "-cp", ".", "Bar");
  84         tr.assertZero("testDoPrivileged fails");
  85         barJava.delete();
  86         barClass.delete();
  87         jarFile.delete();
  88     }
  89 }
  90 
  91 /*
  92  * support infrastructure to invoke a java class from the command line
  93  */
  94 class LUtils {
  95     static final sun.tools.jar.Main jarTool =
  96             new sun.tools.jar.Main(System.out, System.err, "jar-tool");
  97     static final com.sun.tools.javac.Main javac =
  98             new com.sun.tools.javac.Main();
  99     static final File cwd = new File(".").getAbsoluteFile();
 100     static final String JAVAHOME = System.getProperty("java.home");
 101     static final boolean isWindows =
 102             System.getProperty("os.name", "unknown").startsWith("Windows");
 103     //static final boolean isSDK = JAVAHOME.endsWith("jre");
 104     static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
 105     static final File JAVA_CMD = new File(JAVA_BIN_FILE,
 106             isWindows ? "java.exe" : "java");
 107 
 108     protected LUtils() {
 109     }
 110 
 111     public static void compile(String... args) {
 112         if (javac.compile(args) != 0) {
 113             throw new RuntimeException("compilation fails");
 114         }
 115     }
 116 
 117     static void createFile(File outFile, List<String> content) {
 118         try {
 119             Files.write(outFile.getAbsoluteFile().toPath(), content,
 120                     Charset.defaultCharset());
 121         } catch (IOException ex) {
 122             throw new RuntimeException(ex);
 123         }
 124     }
 125 
 126     static File getClassFile(File javaFile) {
 127         return javaFile.getName().endsWith(".java")
 128                 ? new File(javaFile.getName().replace(".java", ".class"))
 129                 : null;
 130     }
 131 
 132     static String getSimpleName(File inFile) {
 133         String fname = inFile.getName();
 134         return fname.substring(0, fname.indexOf("."));
 135     }
 136 
 137     static TestResult doExec(String... cmds) {
 138         return doExec(null, null, cmds);
 139     }
 140 
 141     /*
 142      * A method which executes a java cmd and returns the results in a container
 143      */
 144     static TestResult doExec(Map<String, String> envToSet,
 145             java.util.Set<String> envToRemove, String... cmds) {
 146         String cmdStr = "";
 147         for (String x : cmds) {
 148             cmdStr = cmdStr.concat(x + " ");
 149         }
 150         ProcessBuilder pb = new ProcessBuilder(cmds);
 151         Map<String, String> env = pb.environment();
 152         if (envToRemove != null) {
 153             for (String key : envToRemove) {
 154                 env.remove(key);
 155             }
 156         }
 157         if (envToSet != null) {
 158             env.putAll(envToSet);
 159         }
 160         BufferedReader rdr = null;
 161         try {
 162             List<String> outputList = new ArrayList<>();
 163             pb.redirectErrorStream(true);
 164             Process p = pb.start();
 165             rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
 166             String in = rdr.readLine();
 167             while (in != null) {
 168                 outputList.add(in);
 169                 in = rdr.readLine();
 170             }
 171             p.waitFor();
 172             p.destroy();
 173 
 174             return new TestResult(cmdStr, p.exitValue(), outputList,
 175                     env, new Throwable("current stack of the test"));
 176         } catch (Exception ex) {
 177             ex.printStackTrace();
 178             throw new RuntimeException(ex.getMessage());
 179         }
 180     }
 181 
 182     static class TestResult {
 183         String cmd;
 184         int exitValue;
 185         List<String> testOutput;
 186         Map<String, String> env;
 187         Throwable t;
 188 
 189         public TestResult(String str, int rv, List<String> oList,
 190                 Map<String, String> env, Throwable t) {
 191             cmd = str;
 192             exitValue = rv;
 193             testOutput = oList;
 194             this.env = env;
 195             this.t = t;
 196         }
 197 
 198         void assertZero(String message) {
 199             if (exitValue != 0) {
 200                 System.err.println(this);
 201                 throw new RuntimeException(message);
 202             }
 203         }
 204 
 205         @Override
 206         public String toString() {
 207             StringWriter sw = new StringWriter();
 208             PrintWriter status = new PrintWriter(sw);
 209             status.println("Cmd: " + cmd);
 210             status.println("Return code: " + exitValue);
 211             status.println("Environment variable:");
 212             for (String x : env.keySet()) {
 213                 status.println("\t" + x + "=" + env.get(x));
 214             }
 215             status.println("Output:");
 216             for (String x : testOutput) {
 217                 status.println("\t" + x);
 218             }
 219             status.println("Exception:");
 220             status.println(t.getMessage());
 221             t.printStackTrace(status);
 222 
 223             return sw.getBuffer().toString();
 224         }
 225     }
 226 }