• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.lang;
19 
20 // BEGIN android-added
21 
22 import dalvik.system.VMStack;
23 import java.io.File;
24 import java.io.FileDescriptor;
25 import java.io.FilePermission;
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Member;
29 import java.net.InetAddress;
30 import java.net.SocketPermission;
31 import java.security.AccessControlContext;
32 import java.security.AccessController;
33 import java.security.AllPermission;
34 import java.security.Permission;
35 import java.security.Security;
36 import java.security.SecurityPermission;
37 import java.util.PropertyPermission;
38 import org.apache.harmony.luni.util.PriviAction;
39 
40 /**
41  * <strong>Warning:</strong> security managers do <strong>not</strong> provide a
42  * secure environment for executing untrusted code. Untrusted code cannot be
43  * safely isolated within the Dalvik VM.
44  *
45  * <p>Provides security verification facilities for applications. {@code
46  * SecurityManager} contains a set of {@code checkXXX} methods which determine
47  * if it is safe to perform a specific operation such as establishing network
48  * connections, modifying files, and many more. In general, these methods simply
49  * return if they allow the application to perform the operation; if an
50  * operation is not allowed, then they throw a {@link SecurityException}. The
51  * only exception is {@link #checkTopLevelWindow(Object)}, which returns a
52  * boolean to indicate permission.
53  */
54 public class SecurityManager {
55 
56     private static final PropertyPermission READ_WRITE_ALL_PROPERTIES_PERMISSION = new PropertyPermission(
57             "*", "read,write");
58 
59     private static final String PKG_ACC_KEY = "package.access";
60 
61     private static final String PKG_DEF_KEY = "package.definition";
62 
63     /**
64      * Flag to indicate whether a security check is in progress.
65      *
66      * @deprecated Use {@link #checkPermission}
67      */
68     @Deprecated
69     protected boolean inCheck;
70 
71     /**
72      * Constructs a new {@code SecurityManager} instance.
73      * <p>
74      * The {@code RuntimePermission("createSecurityManager")} is checked if a
75      * security manager is installed.
76      */
SecurityManager()77     public SecurityManager() {
78         SecurityManager security = System.getSecurityManager();
79         if (security != null) {
80             security
81                     .checkPermission(RuntimePermission.permissionToCreateSecurityManager);
82         }
83         Class<?> type = Security.class; // initialize Security properties
84         if (type == null) {
85             throw new AssertionError();
86         }
87     }
88 
89     /**
90      * Checks whether the calling thread is allowed to accept socket
91      * connections.
92      *
93      * @param host
94      *            the address of the host that attempts to connect.
95      * @param port
96      *            the port number to check.
97      * @throws NullPointerException
98      *             if {@code host} is {@code null}.
99      * @throws SecurityException
100      *             if the calling thread is not allowed to accept socket
101      *             connections from {@code host} through {@code port}.
102      */
checkAccept(String host, int port)103     public void checkAccept(String host, int port) {
104         if (host == null) {
105             throw new NullPointerException();
106         }
107         checkPermission(new SocketPermission(host + ':' + port, "accept"));
108     }
109 
110     /**
111      * Checks whether the calling thread is allowed to modify the specified
112      * thread.
113      *
114      * @param thread
115      *            the thread to access.
116      * @throws SecurityException
117      *             if the calling thread is not allowed to access {@code thread}.
118      */
checkAccess(Thread thread)119     public void checkAccess(Thread thread) {
120         // Only worry about system threads. Dead threads have a null group.
121         ThreadGroup group = thread.getThreadGroup();
122         if ((group != null) && (group.parent == null)) {
123             checkPermission(RuntimePermission.permissionToModifyThread);
124         }
125     }
126 
127     /**
128      * Checks whether the calling thread is allowed to modify the specified
129      * thread group.
130      *
131      * @param group
132      *            the thread group to access.
133      * @throws NullPointerException
134      *             if {@code group} is {@code null}.
135      * @throws SecurityException
136      *             if the calling thread is not allowed to access {@code group}.
137      */
checkAccess(ThreadGroup group)138     public void checkAccess(ThreadGroup group) {
139         // Only worry about system threads.
140         if (group == null) {
141             throw new NullPointerException();
142         }
143         if (group.parent == null) {
144             checkPermission(RuntimePermission.permissionToModifyThreadGroup);
145         }
146     }
147 
148     /**
149      * Checks whether the calling thread is allowed to establish socket
150      * connections. A -1 port indicates the caller is trying to resolve the
151      * hostname.
152      *
153      * @param host
154      *            the address of the host to connect to.
155      * @param port
156      *            the port number to check, or -1 for resolve.
157      * @throws NullPointerException
158      *             if {@code host} is {@code null}.
159      * @throws SecurityException
160      *             if the calling thread is not allowed to connect to {@code
161      *             host} through {@code port}.
162      */
checkConnect(String host, int port)163     public void checkConnect(String host, int port) {
164         if (host == null) {
165             throw new NullPointerException();
166         }
167         if (port > 0) {
168             checkPermission(new SocketPermission(host + ':' + port, "connect"));
169         } else {
170             checkPermission(new SocketPermission(host, "resolve"));
171         }
172     }
173 
174     /**
175      * Checks whether the specified security context is allowed to establish
176      * socket connections. A -1 port indicates the caller is trying to resolve
177      * the hostname.
178      *
179      * @param host
180      *            the address of the host to connect to.
181      * @param port
182      *            the port number to check, or -1 for resolve.
183      * @param context
184      *            the security context to use for the check.
185      * @throws NullPointerException
186      *             if {@code host} is {@code null}.
187      * @throws SecurityException
188      *             if {@code context} is not allowed to connect to {@code host}
189      *             through {@code port}.
190      */
checkConnect(String host, int port, Object context)191     public void checkConnect(String host, int port, Object context) {
192         // BEGIN android-added
193         if (host == null) {
194             throw new NullPointerException();
195         }
196         // END android-added
197         if (port > 0) {
198             checkPermission(new SocketPermission(host + ':' + port, "connect"),
199                     context);
200         } else {
201             checkPermission(new SocketPermission(host, "resolve"), context);
202         }
203     }
204 
205     /**
206      * Checks whether the calling thread is allowed to create a class loader.
207      *
208      * @throws SecurityException
209      *             if the calling thread is not allowed to create a class
210      *             loader.
211      */
checkCreateClassLoader()212     public void checkCreateClassLoader() {
213         checkPermission(RuntimePermission.permissionToCreateClassLoader);
214     }
215 
216     /**
217      * Checks whether the calling thread is allowed to delete the file with the
218      * specified name, which should be passed in canonical form.
219      *
220      * @param file
221      *            the name of the file to delete.
222      * @throws SecurityException
223      *             if the calling thread is not allowed to delete {@code file}.
224      */
checkDelete(String file)225     public void checkDelete(String file) {
226         checkPermission(new FilePermission(file, "delete"));
227     }
228 
229     /**
230      * Checks whether the calling thread is allowed to execute the specified
231      * platform specific command.
232      *
233      * @param cmd
234      *            the command line to execute.
235      * @throws SecurityException
236      *             if the calling thread is not allowed to execute {@code cmd}.
237      */
checkExec(String cmd)238     public void checkExec(String cmd) {
239         checkPermission(new FilePermission(new File(cmd).isAbsolute() ? cmd
240                 : "<<ALL FILES>>", "execute"));
241     }
242 
243     /**
244      * Checks whether the calling thread is allowed to terminate the virtual
245      * machine.
246      *
247      * @param status
248      *            the status that the virtual machine returns when it is
249      *            terminated.
250      * @throws SecurityException
251      *             if the calling thread is not allowed to terminate the virtual
252      *             machine with {@code status}.
253      */
checkExit(int status)254     public void checkExit(int status) {
255         checkPermission(RuntimePermission.permissionToExitVM);
256     }
257 
258     /**
259      * Checks whether the calling thread is allowed to load the specified native
260      * library.
261      *
262      * @param libName
263      *            the name of the library to load.
264      * @throws SecurityException
265      *             if the calling thread is not allowed to load {@code libName}.
266      */
checkLink(String libName)267     public void checkLink(String libName) {
268         if (libName == null) {
269             throw new NullPointerException();
270         }
271         checkPermission(new RuntimePermission("loadLibrary." + libName));
272     }
273 
274     /**
275      * Checks whether the calling thread is allowed to listen on the specified
276      * port.
277      *
278      * @param port
279      *            the port number to check.
280      * @throws SecurityException
281      *             if the calling thread is not allowed listen on {@code port}.
282      */
checkListen(int port)283     public void checkListen(int port) {
284         if (port == 0) {
285             checkPermission(new SocketPermission("localhost:1024-", "listen"));
286         } else {
287             checkPermission(new SocketPermission("localhost:" + port, "listen"));
288         }
289     }
290 
291     /**
292      * Checks whether the calling thread is allowed to access members. The
293      * default is to allow access to public members (that is, {@code
294      * java.lang.reflect.Member.PUBLIC}) and to classes loaded by the same
295      * loader as the original caller (that is, the method that called the
296      * reflect API). Due to the nature of the check, overriding implementations
297      * cannot call {@code super.checkMemberAccess()} since the stack would no
298      * longer be of the expected shape.
299      *
300      * @param cls
301      *            the class of which members are accessed.
302      * @param type
303      *            the access type, either {@code
304      *            java.lang.reflect.Member.PUBLIC} or {@code
305      *            java.lang.reflect.Member.DECLARED}.
306      * @throws SecurityException
307      *             if the calling thread is not allowed to access members of
308      *             {@code cls}.
309      */
checkMemberAccess(Class<?> cls, int type)310     public void checkMemberAccess(Class<?> cls, int type) {
311         if (cls == null) {
312             throw new NullPointerException();
313         }
314         if (type == Member.PUBLIC) {
315             return;
316         }
317         //
318         // Need to compare the classloaders.
319         // Stack shape is
320         // <user code> <- want this class
321         // Class.getDeclared*();
322         // Class.checkMemberAccess();
323         // SecurityManager.checkMemberAccess(); <- current frame
324         //
325         // Use getClassLoaderImpl() since getClassLoader()
326         // returns null for the bootstrap class loader.
327         if (ClassLoader.getStackClassLoader(3) == cls.getClassLoaderImpl()) {
328             return;
329         }
330 
331         // Forward off to the permission mechanism.
332         checkPermission(new RuntimePermission("accessDeclaredMembers"));
333     }
334 
335     /**
336      * Checks whether the calling thread is allowed to use the specified IP
337      * multicast group address.
338      *
339      * @param maddr
340      *            the internet group address to use.
341      * @throws SecurityException
342      *             if the calling thread is not allowed to use {@code maddr}.
343      */
checkMulticast(InetAddress maddr)344     public void checkMulticast(InetAddress maddr) {
345         checkPermission(new SocketPermission(maddr.getHostAddress(),
346                 "accept,connect"));
347     }
348 
349     /**
350      * Checks whether the calling thread is allowed to use the specified IP
351      * multicast group address.
352      *
353      * @param maddr
354      *            the internet group address to use.
355      * @param ttl
356      *            the value in use for multicast send. This parameter is
357      *            ignored.
358      * @throws SecurityException
359      *             if the calling thread is not allowed to use {@code maddr}.
360      * @deprecated use {@link #checkMulticast(java.net.InetAddress)}
361      */
362     @Deprecated
checkMulticast(InetAddress maddr, byte ttl)363     public void checkMulticast(InetAddress maddr, byte ttl) {
364         checkPermission(new SocketPermission(maddr.getHostAddress(),
365                 "accept,connect"));
366     }
367 
368     /**
369      * Checks whether the calling thread is allowed to access the specified
370      * package.
371      *
372      * @param packageName
373      *            the name of the package to access.
374      * @throws SecurityException
375      *             if the calling thread is not allowed to access {@code
376      *             packageName}.
377      */
checkPackageAccess(String packageName)378     public void checkPackageAccess(String packageName) {
379         if (packageName == null) {
380             throw new NullPointerException();
381         }
382         if (checkPackageProperty(PKG_ACC_KEY, packageName)) {
383             checkPermission(new RuntimePermission("accessClassInPackage."
384                     + packageName));
385         }
386     }
387 
388     /**
389      * Checks whether the calling thread is allowed to define new classes in the
390      * specified package.
391      *
392      * @param packageName
393      *            the name of the package to add a class to.
394      * @throws SecurityException
395      *             if the calling thread is not allowed to add classes to
396      *             {@code packageName}.
397      */
checkPackageDefinition(String packageName)398     public void checkPackageDefinition(String packageName) {
399         if (packageName == null) {
400             throw new NullPointerException();
401         }
402         if (checkPackageProperty(PKG_DEF_KEY, packageName)) {
403             checkPermission(new RuntimePermission("defineClassInPackage."
404                     + packageName));
405         }
406     }
407 
408     /**
409      * Returns true if the package name is restricted by the specified security
410      * property.
411      */
checkPackageProperty(final String property, final String pkg)412     private static boolean checkPackageProperty(final String property,
413             final String pkg) {
414         String list = AccessController.doPrivileged(PriviAction
415                 .getSecurityProperty(property));
416         if (list != null) {
417             int plen = pkg.length();
418             String[] tokens = list.split(", *");
419             for (String token : tokens) {
420                 int tlen = token.length();
421                 if (plen > tlen
422                         && pkg.startsWith(token)
423                         && (token.charAt(tlen - 1) == '.' || pkg.charAt(tlen) == '.')) {
424                     return true;
425                 } else if (plen == tlen && token.startsWith(pkg)) {
426                     return true;
427                 } else if (plen + 1 == tlen && token.startsWith(pkg)
428                         && token.charAt(tlen - 1) == '.') {
429                     return true;
430                 }
431             }
432         }
433 
434         return false;
435     }
436 
437     /**
438      * Checks whether the calling thread is allowed to access the system
439      * properties.
440      *
441      * @throws SecurityException
442      *             if the calling thread is not allowed to access system
443      *             properties.
444      */
checkPropertiesAccess()445     public void checkPropertiesAccess() {
446         checkPermission(READ_WRITE_ALL_PROPERTIES_PERMISSION);
447     }
448 
449     /**
450      * Checks whether the calling thread is allowed to access a particular
451      * system property.
452      *
453      * @param key
454      *            the name of the property to access.
455      * @throws SecurityException
456      *             if the calling thread is not allowed to access the {@code
457      *             key} system property.
458      */
checkPropertyAccess(String key)459     public void checkPropertyAccess(String key) {
460         checkPermission(new PropertyPermission(key, "read"));
461     }
462 
463     /**
464      * Checks whether the calling thread is allowed to read from the file with
465      * the specified file descriptor.
466      *
467      * @param fd
468      *            the file descriptor of the file to read from.
469      * @throws SecurityException
470      *             if the calling thread is not allowed to read from {@code fd}.
471      */
checkRead(FileDescriptor fd)472     public void checkRead(FileDescriptor fd) {
473         if (fd == null) {
474             throw new NullPointerException();
475         }
476         checkPermission(RuntimePermission.permissionToReadFileDescriptor);
477     }
478 
479     /**
480      * Checks whether the calling thread is allowed to read from the file with
481      * the specified name, which should be passed in canonical form.
482      *
483      * @param file
484      *            the name of the file or directory to read from.
485      * @throws SecurityException
486      *             if the calling thread is not allowed to read from {@code
487      *             file}.
488      */
checkRead(String file)489     public void checkRead(String file) {
490         checkPermission(new FilePermission(file, "read"));
491     }
492 
493     /**
494      * Checks whether the given security context is allowed to read from the
495      * file named by the argument, which should be passed in canonical form.
496      *
497      * @param file
498      *            the name of the file or directory to check.
499      * @param context
500      *            the security context to use for the check.
501      * @throws SecurityException
502      *             if {@code context} is not allowed to read from {@code file}.
503      */
checkRead(String file, Object context)504     public void checkRead(String file, Object context) {
505         checkPermission(new FilePermission(file, "read"), context);
506     }
507 
508     /**
509      * Checks whether the calling thread is allowed to perform the security
510      * operation named by the target.
511      *
512      * @param target
513      *            the name of the operation to perform.
514      * @throws SecurityException
515      *             if the calling thread is not allowed to perform
516      *             {@code target}.
517      */
checkSecurityAccess(String target)518     public void checkSecurityAccess(String target) {
519         checkPermission(new SecurityPermission(target));
520     }
521 
522     /**
523      * Checks whether the calling thread is allowed to set the net object
524      * factories.
525      *
526      * @throws SecurityException
527      *             if the calling thread is not allowed to set the net object
528      *             factories.
529      */
checkSetFactory()530     public void checkSetFactory() {
531         checkPermission(RuntimePermission.permissionToSetFactory);
532     }
533 
534     /**
535      * Checks whether the calling thread is trusted to show the specified top
536      * level window.
537      *
538      * @param window
539      *            the window to show.
540      * @return {@code true} if the calling thread is allowed to show {@code
541      *         window}; {@code false} otherwise.
542      * @throws NullPointerException
543      *             if {@code window} is {@code null}.
544      */
checkTopLevelWindow(Object window)545     public boolean checkTopLevelWindow(Object window) {
546         if (window == null) {
547             throw new NullPointerException();
548         }
549         try {
550             Class<?> awtPermission = Class.forName("java.awt.AWTPermission");
551             Constructor<?> constructor = awtPermission
552                     .getConstructor(String.class);
553             Object perm = constructor
554                     .newInstance("showWindowWithoutWarningBanner");
555             checkPermission((Permission) perm);
556         } catch (ClassNotFoundException e) {
557         } catch (NoSuchMethodException e) {
558         } catch (InstantiationException e) {
559         } catch (IllegalAccessException e) {
560         } catch (InvocationTargetException e) {
561         } catch (SecurityException e) {
562             return false;
563         }
564         return true;
565     }
566 
567     /**
568      * Checks whether the calling thread is allowed to access the system
569      * clipboard.
570      *
571      * @throws SecurityException
572      *             if the calling thread is not allowed to access the system
573      *             clipboard.
574      */
checkSystemClipboardAccess()575     public void checkSystemClipboardAccess() {
576         try {
577             Class<?> awtPermission = Class.forName("java.awt.AWTPermission");
578             Constructor<?> constructor = awtPermission
579                     .getConstructor(String.class);
580             Object perm = constructor.newInstance("accessClipboard");
581             checkPermission((Permission) perm);
582             return;
583         } catch (ClassNotFoundException e) {
584         } catch (NoSuchMethodException e) {
585         } catch (InstantiationException e) {
586         } catch (IllegalAccessException e) {
587         } catch (InvocationTargetException e) {
588         }
589         throw new SecurityException();
590     }
591 
592     /**
593      * Checks whether the calling thread is allowed to access the AWT event
594      * queue.
595      *
596      * @throws SecurityException
597      *             if the calling thread is not allowed to access the AWT event
598      *             queue.
599      */
checkAwtEventQueueAccess()600     public void checkAwtEventQueueAccess() {
601         try {
602             Class<?> awtPermission = Class.forName("java.awt.AWTPermission");
603             Constructor<?> constructor = awtPermission
604                     .getConstructor(String.class);
605             Object perm = constructor.newInstance("accessEventQueue");
606             checkPermission((Permission) perm);
607             return;
608         } catch (ClassNotFoundException e) {
609         } catch (NoSuchMethodException e) {
610         } catch (InstantiationException e) {
611         } catch (IllegalAccessException e) {
612         } catch (InvocationTargetException e) {
613         }
614         throw new SecurityException();
615     }
616 
617     /**
618      * Checks whether the calling thread is allowed to start a new print job.
619      *
620      * @throws SecurityException
621      *             if the calling thread is not allowed to start a new print
622      *             job.
623      */
checkPrintJobAccess()624     public void checkPrintJobAccess() {
625         checkPermission(RuntimePermission.permissionToQueuePrintJob);
626     }
627 
628     /**
629      * Checks whether the calling thread is allowed to write to the file with
630      * the specified file descriptor.
631      *
632      * @param fd
633      *            the file descriptor of the file to write to.
634      * @throws SecurityException
635      *             if the calling thread is not allowed to write to {@code fd}.
636      */
checkWrite(FileDescriptor fd)637     public void checkWrite(FileDescriptor fd) {
638         if (fd == null) {
639             throw new NullPointerException();
640         }
641         checkPermission(RuntimePermission.permissionToWriteFileDescriptor);
642     }
643 
644     /**
645      * Checks whether the calling thread is allowed to write to the file with
646      * the specified name, which should be passed in canonical form.
647      *
648      * @param file
649      *            the name of the file or directory to write to.
650      * @throws SecurityException
651      *             if the calling thread is not allowed to write to
652      *             {@code file}.
653      */
checkWrite(String file)654     public void checkWrite(String file) {
655         checkPermission(new FilePermission(file, "write"));
656     }
657 
658     /**
659      * Indicates if this security manager is currently checking something.
660      *
661      * @return {@code true} if this security manager is executing a security
662      *         check method; {@code false} otherwise.
663      * @deprecated Use {@link #checkPermission}.
664      */
665     @Deprecated
getInCheck()666     public boolean getInCheck() {
667         return inCheck;
668     }
669 
670     /**
671      * Returns an array containing one entry for each method in the current
672      * execution stack. Each entry is the {@code java.lang.Class} which
673      * represents the class in which the method is defined.
674      *
675      * @return all classes in the execution stack.
676      */
677     @SuppressWarnings("unchecked")
getClassContext()678     protected Class[] getClassContext() {
679         return VMStack.getClasses(-1, false);
680     }
681 
682     /**
683      * Returns the class loader of the first class in the execution stack whose
684      * class loader is not a system class loader.
685      *
686      * @return the most recent non-system class loader.
687      * @deprecated Use {@link #checkPermission}.
688      */
689     @Deprecated
currentClassLoader()690     protected ClassLoader currentClassLoader() {
691 
692         /*
693          * First, check if AllPermission is allowed. If so, then we are
694          * effectively running in an unsafe environment, so just answer null
695          * (==> everything is a system class).
696          */
697         try {
698             checkPermission(new AllPermission());
699             return null;
700         } catch (SecurityException ex) {
701         }
702 
703         /*
704          * Now, check if there are any non-system class loaders in the stack up
705          * to the first privileged method (or the end of the stack.
706          */
707         Class<?>[] classes = Class.getStackClasses(-1, true);
708         for (int i = 0; i < classes.length; i++) {
709             ClassLoader cl = classes[i].getClassLoaderImpl();
710             if (!cl.isSystemClassLoader()) {
711                 return cl;
712             }
713         }
714         return null;
715     }
716 
717     /**
718      * Returns the index in the call stack of the first class whose class loader
719      * is not a system class loader.
720      *
721      * @return the frame index of the first method whose class was loaded by a
722      *         non-system class loader.
723      * @deprecated Use {@link #checkPermission}.
724      */
725     @Deprecated
classLoaderDepth()726     protected int classLoaderDepth() {
727         /*
728          * First, check if AllPermission is allowed. If so, then we are
729          * effectively running in an unsafe environment, so just answer -1 (==>
730          * everything is a system class).
731          */
732         try {
733             checkPermission(new AllPermission());
734             return -1;
735         } catch (SecurityException ex) {
736         }
737 
738         /*
739          * Now, check if there are any non-system class loaders in the stack up
740          * to the first privileged method (or the end of the stack.
741          */
742         Class<?>[] classes = Class.getStackClasses(-1, true);
743         for (int i = 0; i < classes.length; i++) {
744             ClassLoader cl = classes[i].getClassLoaderImpl();
745             if (!cl.isSystemClassLoader()) {
746                 return i;
747             }
748         }
749         return -1;
750     }
751 
752     /**
753      * Returns the first class in the call stack that was loaded by a class
754      * loader which is not a system class loader.
755      *
756      * @return the most recent class loaded by a non-system class loader.
757      * @deprecated Use {@link #checkPermission}.
758      */
759     @Deprecated
currentLoadedClass()760     protected Class<?> currentLoadedClass() {
761         /*
762          * First, check if AllPermission is allowed. If so, then we are
763          * effectively running in an unsafe environment, so just answer null
764          * (==> everything is a system class).
765          */
766         try {
767             checkPermission(new AllPermission());
768             return null;
769         } catch (SecurityException ex) {
770         }
771 
772         /*
773          * Now, check if there are any non-system class loaders in the stack up
774          * to the first privileged method (or the end of the stack.
775          */
776         Class<?>[] classes = Class.getStackClasses(-1, true);
777         for (int i = 0; i < classes.length; i++) {
778             ClassLoader cl = classes[i].getClassLoaderImpl();
779             if (!cl.isSystemClassLoader()) {
780                 return classes[i];
781             }
782         }
783         return null;
784     }
785 
786     /**
787      * Returns the index in the call stack of the first method which is
788      * contained in the class with the specified name. Returns -1 if no methods
789      * from this class are in the stack.
790      *
791      * @param name
792      *            the name of the class to look for.
793      * @return the frame index of the first method found is contained in the
794      *         class identified by {@code name}.
795      * @deprecated Use {@link #checkPermission}.
796      */
797     @Deprecated
classDepth(String name)798     protected int classDepth(String name) {
799         Class<?>[] classes = Class.getStackClasses(-1, false);
800         for (int i = 0; i < classes.length; i++) {
801             if (classes[i].getName().equals(name)) {
802                 return i;
803             }
804         }
805         return -1;
806     }
807 
808     /**
809      * Indicates whether there is a method in the call stack from the class with
810      * the specified name.
811      *
812      * @param name
813      *            the name of the class to look for.
814      * @return {@code true} if a method from the class identified by {@code
815      *         name} is executing; {@code false} otherwise.
816      * @deprecated Use {@link #checkPermission}.
817      */
818     @Deprecated
inClass(String name)819     protected boolean inClass(String name) {
820         return classDepth(name) != -1;
821     }
822 
823     /**
824      * Indicates whether there is a method in the call stack from a class which
825      * was defined by a non-system class loader.
826      *
827      * @return {@code true} if a method from a class that was defined by a
828      *         non-system class loader is executing; {@code false} otherwise.
829      * @deprecated Use {@link #checkPermission}
830      */
831     @Deprecated
inClassLoader()832     protected boolean inClassLoader() {
833         return currentClassLoader() != null;
834     }
835 
836     /**
837      * Returns the thread group which should be used to instantiate new threads.
838      * By default, this is the same as the thread group of the thread running
839      * this method.
840      *
841      * @return ThreadGroup the thread group to create new threads in.
842      */
getThreadGroup()843     public ThreadGroup getThreadGroup() {
844         return Thread.currentThread().getThreadGroup();
845     }
846 
847     /**
848      * Returns an object which encapsulates the security state of the current
849      * point in the execution. In our case, this is an {@link
850      * java.security.AccessControlContext}.
851      *
852      * @return an object that encapsulates information about the current
853      *         execution environment.
854      */
getSecurityContext()855     public Object getSecurityContext() {
856         return AccessController.getContext();
857     }
858 
859     /**
860      * Checks whether the calling thread is allowed to access the resource being
861      * guarded by the specified permission object.
862      *
863      * @param permission
864      *            the permission to check.
865      * @throws SecurityException
866      *             if the requested {@code permission} is denied according to
867      *             the current security policy.
868      */
checkPermission(Permission permission)869     public void checkPermission(Permission permission) {
870         try {
871             inCheck = true;
872             AccessController.checkPermission(permission);
873         } finally {
874             inCheck = false;
875         }
876     }
877 
878     /**
879      * Checks whether the specified security context is allowed to access the
880      * resource being guarded by the specified permission object.
881      *
882      * @param permission
883      *            the permission to check.
884      * @param context
885      *            the security context for which to check permission.
886      * @throws SecurityException
887      *             if {@code context} is not an instance of {@code
888      *             AccessControlContext} or if the requested {@code permission}
889      *             is denied for {@code context} according to the current
890      *             security policy.
891      */
checkPermission(Permission permission, Object context)892     public void checkPermission(Permission permission, Object context) {
893         try {
894             inCheck = true;
895             // Must be an AccessControlContext. If we don't check
896             // this, then applications could pass in an arbitrary
897             // object which circumvents the security check.
898             if (context instanceof AccessControlContext) {
899                 ((AccessControlContext) context).checkPermission(permission);
900             } else {
901                 throw new SecurityException();
902             }
903         } finally {
904             inCheck = false;
905         }
906     }
907 }
908