1 /*
2  * Copyright (c) 2002, 2021, 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 package jdk.internal.access;
26 import jdk.internal.misc.Unsafe;
27 import java.io.ObjectInputStream;
28 import java.io.FileDescriptor;
29 /** A repository of "shared secrets", which are a mechanism for
30  calling implementation-private methods in another package without
31  using reflection. A package-private class implements a public
32  interface and provides the ability to call package-private methods
33  within that package; the object implementing that interface is
34  provided through a third package to which access is restricted.
35  This framework avoids the primary disadvantage of using reflection
36  for this purpose, namely the loss of compile-time checking. */
37 public class SharedSecrets {
38     // Android-changed: use Unsafe instead of MethodHandles.
39     // private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
40     private static final Unsafe unsafe = Unsafe.getUnsafe();
41     // BEGIN Android-removed: Pruned unused access interfaces.
42     /*
43     private static JavaAWTAccess javaAWTAccess;
44     private static JavaAWTFontAccess javaAWTFontAccess;
45     private static JavaBeansAccess javaBeansAccess;
46     private static JavaLangAccess javaLangAccess;
47     private static JavaLangInvokeAccess javaLangInvokeAccess;
48     private static JavaLangModuleAccess javaLangModuleAccess;
49     private static JavaLangRefAccess javaLangRefAccess;
50     private static JavaLangReflectAccess javaLangReflectAccess;
51     private static JavaIOAccess javaIOAccess;
52     */
53     // END Android-removed: Pruned unused access interfaces.
54     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
55     // BEGIN Android-removed: Pruned unused access interfaces.
56     /*
57     private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
58     private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
59     private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
60     */
61     // END Android-removed: Pruned unused access interfaces.
62     private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
63     // BEGIN Android-removed: Pruned unused access interfaces.
64     /*
65     private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
66     private static JavaNetInetAddressAccess javaNetInetAddressAccess;
67     private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
68     private static JavaNetUriAccess javaNetUriAccess;
69     private static JavaNetURLAccess javaNetURLAccess;
70     private static JavaNioAccess javaNioAccess;
71     */
72     // END Android-removed: Pruned unused access interfaces.
73     private static JavaUtilCollectionAccess javaUtilCollectionAccess;
74     // BEGIN Android-removed: Pruned unused access interfaces.
75     /*
76     private static JavaUtilJarAccess javaUtilJarAccess;
77     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
78     private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess;
79     private static JavaSecurityAccess javaSecurityAccess;
80     private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
81     private static JavaSecuritySpecAccess javaSecuritySpecAccess;
82     private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
83     private static JavaxCryptoSpecAccess javaxCryptoSpecAccess;
84     */
85     // END Android-removed: Pruned unused access interfaces.
setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca)86     public static void setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca) {
87         javaUtilCollectionAccess = juca;
88     }
getJavaUtilCollectionAccess()89     public static JavaUtilCollectionAccess getJavaUtilCollectionAccess() {
90         var access = javaUtilCollectionAccess;
91         if (access == null) {
92             try {
93                 Class.forName("java.util.ImmutableCollections$Access", true, null);
94                 access = javaUtilCollectionAccess;
95             } catch (ClassNotFoundException e) {}
96         }
97         return access;
98     }
99     // BEGIN Android-removed: Pruned unused access interfaces.
100     /*
101     public static JavaUtilJarAccess javaUtilJarAccess() {
102         var access = javaUtilJarAccess;
103         if (access == null) {
104             // Ensure JarFile is initialized; we know that this class
105             // provides the shared secret
106             ensureClassInitialized(JarFile.class);
107             access = javaUtilJarAccess;
108         }
109         return access;
110     }
111     public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
112         javaUtilJarAccess = access;
113     }
114     public static void setJavaLangAccess(JavaLangAccess jla) {
115         javaLangAccess = jla;
116     }
117     public static JavaLangAccess getJavaLangAccess() {
118         return javaLangAccess;
119     }
120     public static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) {
121         javaLangInvokeAccess = jlia;
122     }
123     public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
124         var access = javaLangInvokeAccess;
125         if (access == null) {
126             try {
127                 Class.forName("java.lang.invoke.MethodHandleImpl", true, null);
128                 access = javaLangInvokeAccess;
129             } catch (ClassNotFoundException e) {}
130         }
131         return access;
132     }
133     public static void setJavaLangModuleAccess(JavaLangModuleAccess jlrma) {
134         javaLangModuleAccess = jlrma;
135     }
136     public static JavaLangModuleAccess getJavaLangModuleAccess() {
137         var access = javaLangModuleAccess;
138         if (access == null) {
139             ensureClassInitialized(ModuleDescriptor.class);
140             access = javaLangModuleAccess;
141         }
142         return access;
143     }
144     public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
145         javaLangRefAccess = jlra;
146     }
147     public static JavaLangRefAccess getJavaLangRefAccess() {
148         return javaLangRefAccess;
149     }
150     public static void setJavaLangReflectAccess(JavaLangReflectAccess jlra) {
151         javaLangReflectAccess = jlra;
152     }
153     public static JavaLangReflectAccess getJavaLangReflectAccess() {
154         return javaLangReflectAccess;
155     }
156     public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
157         javaNetUriAccess = jnua;
158     }
159     public static JavaNetUriAccess getJavaNetUriAccess() {
160         var access = javaNetUriAccess;
161         if (access == null) {
162             ensureClassInitialized(java.net.URI.class);
163             access = javaNetUriAccess;
164         }
165         return access;
166     }
167     public static void setJavaNetURLAccess(JavaNetURLAccess jnua) {
168         javaNetURLAccess = jnua;
169     }
170     public static JavaNetURLAccess getJavaNetURLAccess() {
171         var access = javaNetURLAccess;
172         if (access == null) {
173             ensureClassInitialized(java.net.URL.class);
174             access = javaNetURLAccess;
175         }
176         return access;
177     }
178     public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
179         javaNetInetAddressAccess = jna;
180     }
181     public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() {
182         var access = javaNetInetAddressAccess;
183         if (access == null) {
184             ensureClassInitialized(java.net.InetAddress.class);
185             access = javaNetInetAddressAccess;
186         }
187         return access;
188     }
189     public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
190         javaNetHttpCookieAccess = a;
191     }
192     public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
193         var access = javaNetHttpCookieAccess;
194         if (access == null) {
195             ensureClassInitialized(java.net.HttpCookie.class);
196             access = javaNetHttpCookieAccess;
197         }
198         return access;
199     }
200     public static void setJavaNioAccess(JavaNioAccess jna) {
201         javaNioAccess = jna;
202     }
203     public static JavaNioAccess getJavaNioAccess() {
204         var access = javaNioAccess;
205         if (access == null) {
206             // Ensure java.nio.Buffer is initialized, which provides the
207             // shared secret.
208             ensureClassInitialized(java.nio.Buffer.class);
209             access = javaNioAccess;
210         }
211         return access;
212     }
213     public static void setJavaIOAccess(JavaIOAccess jia) {
214         javaIOAccess = jia;
215     }
216     public static JavaIOAccess getJavaIOAccess() {
217         var access = javaIOAccess;
218         if (access == null) {
219             ensureClassInitialized(Console.class);
220             access = javaIOAccess;
221         }
222         return access;
223     }
224     */
225     // END Android-removed: Pruned unused access interfaces.
setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda)226     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
227         javaIOFileDescriptorAccess = jiofda;
228     }
229     // BEGIN Android-removed: Pruned unused access interfaces.
230     /*
231     public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
232         var access = javaIOFilePermissionAccess;
233         if (access == null) {
234             ensureClassInitialized(FilePermission.class);
235             access = javaIOFilePermissionAccess;
236         }
237         return access;
238     }
239     public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
240         javaIOFilePermissionAccess = jiofpa;
241     }
242     */
243     // END Android-removed: Pruned unused access interfaces.
getJavaIOFileDescriptorAccess()244     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
245         var access = javaIOFileDescriptorAccess;
246         if (access == null) {
247             ensureClassInitialized(FileDescriptor.class);
248             access = javaIOFileDescriptorAccess;
249         }
250         return access;
251     }
252     // BEGIN Android-removed: Pruned unused access interfaces.
253     /*
254     public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
255         javaSecurityAccess = jsa;
256     }
257     public static JavaSecurityAccess getJavaSecurityAccess() {
258         var access = javaSecurityAccess;
259         if (access == null) {
260             ensureClassInitialized(ProtectionDomain.class);
261             access = javaSecurityAccess;
262         }
263         return access;
264     }
265     public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
266         var access = javaUtilZipFileAccess;
267         if (access == null) {
268             ensureClassInitialized(java.util.zip.ZipFile.class);
269             access = javaUtilZipFileAccess;
270         }
271         return access;
272     }
273     public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
274         javaUtilZipFileAccess = access;
275     }
276     public static void setJavaAWTAccess(JavaAWTAccess jaa) {
277         javaAWTAccess = jaa;
278     }
279     public static JavaAWTAccess getJavaAWTAccess() {
280         // this may return null in which case calling code needs to
281         // provision for.
282         return javaAWTAccess;
283     }
284     public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) {
285         javaAWTFontAccess = jafa;
286     }
287     public static JavaAWTFontAccess getJavaAWTFontAccess() {
288         // this may return null in which case calling code needs to
289         // provision for.
290         return javaAWTFontAccess;
291     }
292     public static JavaBeansAccess getJavaBeansAccess() {
293         return javaBeansAccess;
294     }
295     public static void setJavaBeansAccess(JavaBeansAccess access) {
296         javaBeansAccess = access;
297     }
298     public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() {
299         var access = javaUtilResourceBundleAccess;
300         if (access == null) {
301             ensureClassInitialized(ResourceBundle.class);
302             access = javaUtilResourceBundleAccess;
303         }
304         return access;
305     }
306     public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) {
307         javaUtilResourceBundleAccess = access;
308     }
309     public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
310         var access = javaObjectInputStreamReadString;
311         if (access == null) {
312             ensureClassInitialized(ObjectInputStream.class);
313             access = javaObjectInputStreamReadString;
314         }
315         return access;
316     }
317     public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
318         javaObjectInputStreamReadString = access;
319     }
320     */
321     // END Android-removed: Pruned unused access interfaces.
getJavaObjectInputStreamAccess()322     public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
323         var access = javaObjectInputStreamAccess;
324         if (access == null) {
325             ensureClassInitialized(ObjectInputStream.class);
326             access = javaObjectInputStreamAccess;
327         }
328         return access;
329     }
setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access)330     public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
331         javaObjectInputStreamAccess = access;
332     }
333     // BEGIN Android-removed: Pruned unused access interfaces.
334     /*
335     public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
336         var access = javaObjectInputFilterAccess;
337         if (access == null) {
338             ensureClassInitialized(ObjectInputFilter.Config.class);
339             access = javaObjectInputFilterAccess;
340         }
341         return access;
342     }
343     public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) {
344         javaObjectInputFilterAccess = access;
345     }
346     public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) {
347         javaIORandomAccessFileAccess = jirafa;
348     }
349     public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
350         var access = javaIORandomAccessFileAccess;
351         if (access == null) {
352             ensureClassInitialized(RandomAccessFile.class);
353             access = javaIORandomAccessFileAccess;
354         }
355         return access;
356     }
357     public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
358         javaSecuritySignatureAccess = jssa;
359     }
360     public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
361         var access = javaSecuritySignatureAccess;
362         if (access == null) {
363             ensureClassInitialized(Signature.class);
364             access = javaSecuritySignatureAccess;
365         }
366         return access;
367     }
368     public static void setJavaSecuritySpecAccess(JavaSecuritySpecAccess jssa) {
369         javaSecuritySpecAccess = jssa;
370     }
371     public static JavaSecuritySpecAccess getJavaSecuritySpecAccess() {
372         if (javaSecuritySpecAccess == null) {
373             ensureClassInitialized(EncodedKeySpec.class);
374         }
375         return javaSecuritySpecAccess;
376     }
377     public static void setJavaxCryptoSpecAccess(JavaxCryptoSpecAccess jcsa) {
378         javaxCryptoSpecAccess = jcsa;
379     }
380     public static JavaxCryptoSpecAccess getJavaxCryptoSpecAccess() {
381         if (javaxCryptoSpecAccess == null) {
382             ensureClassInitialized(SecretKeySpec.class);
383         }
384         return javaxCryptoSpecAccess;
385     }
386     public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
387         javaxCryptoSealedObjectAccess = jcsoa;
388     }
389     public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
390         var access = javaxCryptoSealedObjectAccess;
391         if (access == null) {
392             ensureClassInitialized(SealedObject.class);
393             access = javaxCryptoSealedObjectAccess;
394         }
395         return access;
396     }
397     */
398     // END Android-removed: Pruned unused access interfaces.
ensureClassInitialized(Class<?> c)399     private static void ensureClassInitialized(Class<?> c) {
400         // Android-changed: MH.Lookup.ensureInitialized is not yet available, use Unsafe.
401         /*
402         try {
403             MethodHandles.lookup().ensureInitialized(c);
404         } catch (IllegalAccessException e) {}
405         */
406         unsafe.ensureClassInitialized(c);
407     }
408 }
409