1 /*
   2  * Copyright (c) 2012, 2018, 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 6741606 7146431 8000450 8019830 8022945 8027144 8041633 8078427 8055206
  27  *  @summary Check that various restricted packages that are supposed to be
  28  *           restricted by default or are listed in the package.access
  29  *           property in the java.security file are blocked
  30  *  @run main/othervm CheckPackageAccess
  31  */
  32 
  33 import java.lang.module.ModuleFinder;
  34 import java.lang.module.ModuleReference;
  35 import java.util.Arrays;
  36 import java.util.List;
  37 import java.util.Optional;
  38 
  39 public class CheckPackageAccess {
  40 
  41     private static final SecurityManager sm = new SecurityManager();
  42     private static final ModuleFinder mf = ModuleFinder.ofSystem();
  43 
  44     /*
  45      * The expected list of restricted packages of the package.access property.
  46      *
  47      * This array should be updated whenever new packages are added to the
  48      * package.access property in the java.security file
  49      * NOTE: it should be in the same order as the java.security file
  50      */
  51     private static final String[] EXPECTED = {
  52         "sun.misc.",
  53         "sun.reflect.",
  54     };
  55 
  56     /**
  57      * Tests access to various packages of a module.
  58      */
  59     private static class Test {
  60         String moduleName;     // name of module
  61         ModuleReference moduleRef;     // module reference
  62         String exports;    // exported pkg
  63         Optional<String> opens;      // opened pkg
  64         String conceals;   // concealed pkg
  65         Optional<String> qualExports; // qualified export pkg
  66         Optional<String> qualOpens;   // qualified open pkg
  67         // qual open and non-qualified export pkg
  68         Optional<String> qualOpensAndExports;
  69         Test(String module, String exports, String opens, String conceals,
  70              String qualExports, String qualOpens, String qualOpensAndExports) {
  71             this.moduleName = module;
  72             this.moduleRef = mf.find(moduleName).get();
  73             this.exports = exports;
  74             this.opens = Optional.ofNullable(opens);
  75             this.conceals = conceals;
  76             this.qualExports = Optional.ofNullable(qualExports);
  77             this.qualOpens = Optional.ofNullable(qualOpens);
  78             this.qualOpensAndExports = Optional.ofNullable(qualOpensAndExports);
  79         }
  80 
  81         void test() {
  82             final boolean isModulePresent =
  83                         ModuleLayer.boot().findModule(moduleName).isPresent();
  84             System.out.format("Testing module: %1$s. Module is%2$s present.\n",
  85                         moduleName, isModulePresent ? "" : " NOT");
  86 
  87             if (isModulePresent) {
  88 
  89                 // access to exported pkg should pass
  90                 testNonRestricted(exports);
  91 
  92                 // access to opened pkg should pass
  93                 opens.ifPresent(Test::testNonRestricted);
  94 
  95                 // access to concealed pkg should fail
  96                 testRestricted(conceals);
  97 
  98                 // access to qualified export pkg should fail
  99                 qualExports.ifPresent(Test::testRestricted);
 100 
 101                 // access to qualified open pkg should fail
 102                 qualOpens.ifPresent(Test::testRestricted);
 103 
 104                 // access to qualified opened pkg that is also exported should pass
 105                 qualOpensAndExports.ifPresent(Test::testNonRestricted);
 106             } else {
 107                 System.out.println("Skipping tests for module.");
 108             }
 109         }
 110 
 111         private static void testRestricted(String pkg) {
 112             try {
 113                 sm.checkPackageAccess(pkg);
 114                 throw new RuntimeException("Able to access restricted package: "
 115                                            + pkg);
 116             } catch (SecurityException se) {}
 117             try {
 118                 sm.checkPackageDefinition(pkg);
 119                 throw new RuntimeException("Able to access restricted package: "
 120                                            + pkg);
 121             } catch (SecurityException se) {}
 122         }
 123 
 124         private static void testNonRestricted(String pkg) {
 125             try {
 126                 sm.checkPackageAccess(pkg);
 127             } catch (SecurityException se) {
 128                 throw new RuntimeException("Unable to access exported package: "
 129                                            + pkg, se);
 130             }
 131             try {
 132                 sm.checkPackageDefinition(pkg);
 133             } catch (SecurityException se) {
 134                 throw new RuntimeException("Unable to access exported package: "
 135                                            + pkg, se);
 136             }
 137         }
 138     }
 139 
 140     private static final Test[] tests = new Test[] {
 141         // java.base module loaded by boot loader
 142         new Test("java.base", "java.security", null, "jdk.internal.jrtfs",
 143                  "jdk.internal.loader", null, null),
 144         // java.desktop module loaded by boot loader and has an openQual pkg
 145         // that is exported
 146         new Test("java.desktop", "java.applet", null, "sun.applet",
 147                  "sun.awt", null, "javax.swing.plaf.basic"),
 148         // java.security.jgss module loaded by platform loader
 149         new Test("java.security.jgss", "org.ietf.jgss", null,
 150                  "sun.security.krb5.internal.crypto", "sun.security.krb5",
 151                  null, null),
 152     };
 153 
 154     public static void main(String[] args) throws Exception {
 155 
 156         // check expected list of restricted packages in java.security file
 157         checkPackages(Arrays.asList(EXPECTED));
 158 
 159         // check access to each module's packages
 160         for (Test test : tests) {
 161             test.test();
 162         }
 163 
 164         System.out.println("Test passed");
 165     }
 166 
 167     private static void checkPackages(List<String> pkgs) {
 168         for (String pkg : pkgs) {
 169             try {
 170                 sm.checkPackageAccess(pkg);
 171                 throw new RuntimeException("Able to access " + pkg +
 172                                            " package");
 173             } catch (SecurityException se) { }
 174             try {
 175                 sm.checkPackageDefinition(pkg);
 176                 throw new RuntimeException("Able to define class in " + pkg +
 177                                            " package");
 178             } catch (SecurityException se) { }
 179             String subpkg = pkg + "foo";
 180             try {
 181                 sm.checkPackageAccess(subpkg);
 182                 throw new RuntimeException("Able to access " + subpkg +
 183                                            " package");
 184             } catch (SecurityException se) { }
 185             try {
 186                 sm.checkPackageDefinition(subpkg);
 187                 throw new RuntimeException("Able to define class in " +
 188                                            subpkg + " package");
 189             } catch (SecurityException se) { }
 190         }
 191     }
 192 }