1 /*
   2  * Copyright (c) 2002, 2019, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.access;
  27 
  28 import javax.crypto.SealedObject;
  29 import java.io.ObjectInputFilter;
  30 import java.lang.module.ModuleDescriptor;
  31 import java.util.ResourceBundle;
  32 import java.util.jar.JarFile;
  33 import java.io.Console;
  34 import java.io.FileDescriptor;
  35 import java.io.FilePermission;
  36 import java.io.ObjectInputStream;
  37 import java.io.RandomAccessFile;
  38 import java.security.ProtectionDomain;
  39 import java.security.Signature;
  40 import jdk.internal.misc.Unsafe;
  41 
  42 /** A repository of "shared secrets", which are a mechanism for
  43     calling implementation-private methods in another package without
  44     using reflection. A package-private class implements a public
  45     interface and provides the ability to call package-private methods
  46     within that package; the object implementing that interface is
  47     provided through a third package to which access is restricted.
  48     This framework avoids the primary disadvantage of using reflection
  49     for this purpose, namely the loss of compile-time checking. */
  50 
  51 public class SharedSecrets {
  52     private static final Unsafe unsafe = Unsafe.getUnsafe();
  53     private static JavaUtilJarAccess javaUtilJarAccess;
  54     private static JavaLangAccess javaLangAccess;
  55     private static JavaLangModuleAccess javaLangModuleAccess;
  56     private static JavaLangInvokeAccess javaLangInvokeAccess;
  57     private static JavaLangRefAccess javaLangRefAccess;
  58     private static JavaIOAccess javaIOAccess;
  59     private static JavaNetInetAddressAccess javaNetInetAddressAccess;
  60     private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
  61     private static JavaNetSocketAccess javaNetSocketAccess;
  62     private static JavaNetUriAccess javaNetUriAccess;
  63     private static JavaNetURLAccess javaNetURLAccess;
  64     private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
  65     private static JavaNioAccess javaNioAccess;
  66     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
  67     private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
  68     private static JavaSecurityAccess javaSecurityAccess;
  69     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
  70     private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess;
  71     private static JavaAWTAccess javaAWTAccess;
  72     private static JavaAWTFontAccess javaAWTFontAccess;
  73     private static JavaBeansAccess javaBeansAccess;
  74     private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
  75     private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
  76     private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
  77     private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
  78     private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
  79 
  80     public static JavaUtilJarAccess javaUtilJarAccess() {
  81         if (javaUtilJarAccess == null) {
  82             // Ensure JarFile is initialized; we know that this class
  83             // provides the shared secret
  84             unsafe.ensureClassInitialized(JarFile.class);
  85         }
  86         return javaUtilJarAccess;
  87     }
  88 
  89     public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
  90         javaUtilJarAccess = access;
  91     }
  92 
  93     public static void setJavaLangAccess(JavaLangAccess jla) {
  94         javaLangAccess = jla;
  95     }
  96 
  97     public static JavaLangAccess getJavaLangAccess() {
  98         return javaLangAccess;
  99     }
 100 
 101     public static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) {
 102         javaLangInvokeAccess = jlia;
 103     }
 104 
 105     public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
 106         if (javaLangInvokeAccess == null) {
 107             try {
 108                 Class<?> c = Class.forName("java.lang.invoke.MethodHandleImpl");
 109                 unsafe.ensureClassInitialized(c);
 110             } catch (ClassNotFoundException e) {};
 111         }
 112         return javaLangInvokeAccess;
 113     }
 114 
 115     public static void setJavaLangModuleAccess(JavaLangModuleAccess jlrma) {
 116         javaLangModuleAccess = jlrma;
 117     }
 118 
 119     public static JavaLangModuleAccess getJavaLangModuleAccess() {
 120         if (javaLangModuleAccess == null) {
 121             unsafe.ensureClassInitialized(ModuleDescriptor.class);
 122         }
 123         return javaLangModuleAccess;
 124     }
 125 
 126     public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
 127         javaLangRefAccess = jlra;
 128     }
 129 
 130     public static JavaLangRefAccess getJavaLangRefAccess() {
 131         return javaLangRefAccess;
 132     }
 133 
 134     public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
 135         javaNetUriAccess = jnua;
 136     }
 137 
 138     public static JavaNetUriAccess getJavaNetUriAccess() {
 139         if (javaNetUriAccess == null)
 140             unsafe.ensureClassInitialized(java.net.URI.class);
 141         return javaNetUriAccess;
 142     }
 143 
 144     public static void setJavaNetURLAccess(JavaNetURLAccess jnua) {
 145         javaNetURLAccess = jnua;
 146     }
 147 
 148     public static JavaNetURLAccess getJavaNetURLAccess() {
 149         if (javaNetURLAccess == null)
 150             unsafe.ensureClassInitialized(java.net.URL.class);
 151         return javaNetURLAccess;
 152     }
 153 
 154     public static void setJavaNetURLClassLoaderAccess(JavaNetURLClassLoaderAccess jnua) {
 155         javaNetURLClassLoaderAccess = jnua;
 156     }
 157 
 158     public static JavaNetURLClassLoaderAccess getJavaNetURLClassLoaderAccess() {
 159         if (javaNetURLClassLoaderAccess == null)
 160             unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
 161         return javaNetURLClassLoaderAccess;
 162     }
 163 
 164     public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
 165         javaNetInetAddressAccess = jna;
 166     }
 167 
 168     public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() {
 169         if (javaNetInetAddressAccess == null)
 170             unsafe.ensureClassInitialized(java.net.InetAddress.class);
 171         return javaNetInetAddressAccess;
 172     }
 173 
 174     public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
 175         javaNetHttpCookieAccess = a;
 176     }
 177 
 178     public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
 179         if (javaNetHttpCookieAccess == null)
 180             unsafe.ensureClassInitialized(java.net.HttpCookie.class);
 181         return javaNetHttpCookieAccess;
 182     }
 183 
 184     public static void setJavaNetSocketAccess(JavaNetSocketAccess jnsa) {
 185         javaNetSocketAccess = jnsa;
 186     }
 187 
 188     public static JavaNetSocketAccess getJavaNetSocketAccess() {
 189         if (javaNetSocketAccess == null)
 190             unsafe.ensureClassInitialized(java.net.ServerSocket.class);
 191         return javaNetSocketAccess;
 192     }
 193 
 194     public static void setJavaNioAccess(JavaNioAccess jna) {
 195         javaNioAccess = jna;
 196     }
 197 
 198     public static JavaNioAccess getJavaNioAccess() {
 199         if (javaNioAccess == null) {
 200             // Ensure java.nio.Buffer is initialized, which provides the
 201             // shared secret.
 202             unsafe.ensureClassInitialized(java.nio.Buffer.class);
 203         }
 204         return javaNioAccess;
 205     }
 206 
 207     public static void setJavaIOAccess(JavaIOAccess jia) {
 208         javaIOAccess = jia;
 209     }
 210 
 211     public static JavaIOAccess getJavaIOAccess() {
 212         if (javaIOAccess == null) {
 213             unsafe.ensureClassInitialized(Console.class);
 214         }
 215         return javaIOAccess;
 216     }
 217 
 218     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
 219         javaIOFileDescriptorAccess = jiofda;
 220     }
 221 
 222     public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
 223         if (javaIOFilePermissionAccess == null)
 224             unsafe.ensureClassInitialized(FilePermission.class);
 225 
 226         return javaIOFilePermissionAccess;
 227     }
 228 
 229     public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
 230         javaIOFilePermissionAccess = jiofpa;
 231     }
 232 
 233     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
 234         if (javaIOFileDescriptorAccess == null)
 235             unsafe.ensureClassInitialized(FileDescriptor.class);
 236 
 237         return javaIOFileDescriptorAccess;
 238     }
 239 
 240     public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
 241         javaSecurityAccess = jsa;
 242     }
 243 
 244     public static JavaSecurityAccess getJavaSecurityAccess() {
 245         if (javaSecurityAccess == null) {
 246             unsafe.ensureClassInitialized(ProtectionDomain.class);
 247         }
 248         return javaSecurityAccess;
 249     }
 250 
 251     public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
 252         if (javaUtilZipFileAccess == null)
 253             unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
 254         return javaUtilZipFileAccess;
 255     }
 256 
 257     public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
 258         javaUtilZipFileAccess = access;
 259     }
 260 
 261     public static void setJavaAWTAccess(JavaAWTAccess jaa) {
 262         javaAWTAccess = jaa;
 263     }
 264 
 265     public static JavaAWTAccess getJavaAWTAccess() {
 266         // this may return null in which case calling code needs to
 267         // provision for.
 268         return javaAWTAccess;
 269     }
 270 
 271     public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) {
 272         javaAWTFontAccess = jafa;
 273     }
 274 
 275     public static JavaAWTFontAccess getJavaAWTFontAccess() {
 276         // this may return null in which case calling code needs to
 277         // provision for.
 278         return javaAWTFontAccess;
 279     }
 280 
 281     public static JavaBeansAccess getJavaBeansAccess() {
 282         return javaBeansAccess;
 283     }
 284 
 285     public static void setJavaBeansAccess(JavaBeansAccess access) {
 286         javaBeansAccess = access;
 287     }
 288 
 289     public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() {
 290         if (javaUtilResourceBundleAccess == null)
 291             unsafe.ensureClassInitialized(ResourceBundle.class);
 292         return javaUtilResourceBundleAccess;
 293     }
 294 
 295     public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) {
 296         javaUtilResourceBundleAccess = access;
 297     }
 298 
 299     public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
 300         if (javaObjectInputStreamAccess == null) {
 301             unsafe.ensureClassInitialized(ObjectInputStream.class);
 302         }
 303         return javaObjectInputStreamAccess;
 304     }
 305 
 306     public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
 307         javaObjectInputStreamAccess = access;
 308     }
 309 
 310     public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
 311         if (javaObjectInputFilterAccess == null) {
 312             unsafe.ensureClassInitialized(ObjectInputFilter.Config.class);
 313         }
 314         return javaObjectInputFilterAccess;
 315     }
 316 
 317     public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) {
 318         javaObjectInputFilterAccess = access;
 319     }
 320 
 321     public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) {
 322         javaIORandomAccessFileAccess = jirafa;
 323     }
 324 
 325     public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
 326         if (javaIORandomAccessFileAccess == null) {
 327             unsafe.ensureClassInitialized(RandomAccessFile.class);
 328         }
 329         return javaIORandomAccessFileAccess;
 330     }
 331 
 332     public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
 333         javaSecuritySignatureAccess = jssa;
 334     }
 335 
 336     public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
 337         if (javaSecuritySignatureAccess == null) {
 338             unsafe.ensureClassInitialized(Signature.class);
 339         }
 340         return javaSecuritySignatureAccess;
 341     }
 342 
 343     public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
 344         javaxCryptoSealedObjectAccess = jcsoa;
 345     }
 346 
 347     public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
 348         if (javaxCryptoSealedObjectAccess == null) {
 349             unsafe.ensureClassInitialized(SealedObject.class);
 350         }
 351         return javaxCryptoSealedObjectAccess;
 352     }
 353 }