OSDN Git Service

Initial revision
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / lang / SecurityManager.java
1 /* SecurityManager.java -- security checks for privileged actions
2    Copyright (C) 1998, 1999, 2001, 2002, 2005  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.lang;
40
41 import gnu.classpath.VMStackWalker;
42
43 import java.awt.AWTPermission;
44 import java.io.File;
45 import java.io.FileDescriptor;
46 import java.io.FilePermission;
47 import java.lang.reflect.Member;
48 import java.net.InetAddress;
49 import java.net.SocketPermission;
50 import java.security.AccessControlContext;
51 import java.security.AccessController;
52 import java.security.AllPermission;
53 import java.security.Permission;
54 import java.security.PrivilegedAction;
55 import java.security.Security;
56 import java.security.SecurityPermission;
57 import java.util.PropertyPermission;
58 import java.util.StringTokenizer;
59
60 /**
61  * SecurityManager is a class you can extend to create your own Java
62  * security policy.  By default, there is no SecurityManager installed in
63  * 1.1, which means that all things are permitted to all people. The security
64  * manager, if set, is consulted before doing anything with potentially
65  * dangerous results, and throws a <code>SecurityException</code> if the
66  * action is forbidden.
67  *
68  * <p>A typical check is as follows, just before the dangerous operation:<br>
69  * <pre>
70  * SecurityManager sm = System.getSecurityManager();
71  * if (sm != null)
72  *   sm.checkABC(<em>argument</em>, ...);
73  * </pre>
74  * Note that this is thread-safe, by caching the security manager in a local
75  * variable rather than risking a NullPointerException if the mangager is
76  * changed between the check for null and before the permission check.
77  *
78  * <p>The special method <code>checkPermission</code> is a catchall, and
79  * the default implementation calls
80  * <code>AccessController.checkPermission</code>. In fact, all the other
81  * methods default to calling checkPermission.
82  *
83  * <p>Sometimes, the security check needs to happen from a different context,
84  * such as when called from a worker thread. In such cases, use
85  * <code>getSecurityContext</code> to take a snapshot that can be passed
86  * to the worker thread:<br>
87  * <pre>
88  * Object context = null;
89  * SecurityManager sm = System.getSecurityManager();
90  * if (sm != null)
91  *   context = sm.getSecurityContext(); // defaults to an AccessControlContext
92  * // now, in worker thread
93  * if (sm != null)
94  *   sm.checkPermission(permission, context);
95  * </pre>
96  *
97  * <p>Permissions fall into these categories: File, Socket, Net, Security,
98  * Runtime, Property, AWT, Reflect, and Serializable. Each of these
99  * permissions have a property naming convention, that follows a hierarchical
100  * naming convention, to make it easy to grant or deny several permissions
101  * at once. Some permissions also take a list of permitted actions, such
102  * as "read" or "write", to fine-tune control even more. The permission
103  * <code>java.security.AllPermission</code> grants all permissions.
104  *
105  * <p>The default methods in this class deny all things to all people. You
106  * must explicitly grant permission for anything you want to be legal when
107  * subclassing this class.
108  *
109  * @author John Keiser
110  * @author Eric Blake (ebb9@email.byu.edu)
111  * @see ClassLoader
112  * @see SecurityException
113  * @see #checkTopLevelWindow(Object)
114  * @see System#getSecurityManager()
115  * @see System#setSecurityManager(SecurityManager)
116  * @see AccessController
117  * @see AccessControlContext
118  * @see AccessControlException
119  * @see Permission
120  * @see BasicPermission
121  * @see java.io.FilePermission
122  * @see java.net.SocketPermission
123  * @see java.util.PropertyPermission
124  * @see RuntimePermission
125  * @see java.awt.AWTPermission
126  * @see Policy
127  * @see SecurityPermission
128  * @see ProtectionDomain
129  * @since 1.0
130  * @status still missing 1.4 functionality
131  */
132 public class SecurityManager
133 {
134   /**
135    * The current security manager. This is located here instead of in
136    * System, to avoid security problems, as well as bootstrap issues.
137    * Make sure to access it in a thread-safe manner; it is package visible
138    * to avoid overhead in java.lang.
139    */
140   static volatile SecurityManager current;
141
142   /**
143    * Tells whether or not the SecurityManager is currently performing a
144    * security check.
145    * @deprecated Use {@link #checkPermission(Permission)} instead.
146    */
147   protected boolean inCheck;
148
149   /**
150    * Construct a new security manager. There may be a security check, of
151    * <code>RuntimePermission("createSecurityManager")</code>.
152    *
153    * @throws SecurityException if permission is denied
154    */
155   public SecurityManager()
156   {
157     SecurityManager sm = System.getSecurityManager();
158     if (sm != null)
159       sm.checkPermission(new RuntimePermission("createSecurityManager"));
160   }
161
162   /**
163    * Tells whether or not the SecurityManager is currently performing a
164    * security check.
165    *
166    * @return true if the SecurityManager is in a security check
167    * @see #inCheck
168    * @deprecated use {@link #checkPermission(Permission)} instead
169    */
170   public boolean getInCheck()
171   {
172     return inCheck;
173   }
174
175   /**
176    * Get a list of all the classes currently executing methods on the Java
177    * stack.  getClassContext()[0] is the currently executing method (ie. the
178    * class that CALLED getClassContext, not SecurityManager).
179    *
180    * @return an array of classes on the Java execution stack
181    */
182   protected Class[] getClassContext()
183   {
184     Class[] stack1 = VMStackWalker.getClassContext();
185     Class[] stack2 = new Class[stack1.length - 1];
186     System.arraycopy(stack1, 1, stack2, 0, stack1.length - 1);
187     return stack2;
188   }
189
190   /**
191    * Find the ClassLoader of the first non-system class on the execution
192    * stack. A non-system class is one whose ClassLoader is not equal to
193    * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
194    * will return null in three cases:
195    *
196    * <ul>
197    * <li>All methods on the stack are from system classes</li>
198    * <li>All methods on the stack up to the first "privileged" caller, as
199    *  created by {@link AccessController.doPrivileged(PrivilegedAction)},
200    *  are from system classes</li>
201    * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
202    * </ul>
203    * 
204    * @return the most recent non-system ClassLoader on the execution stack
205    * @deprecated use {@link #checkPermission(Permission)} instead
206    */
207   protected ClassLoader currentClassLoader()
208   {
209     Class cl = currentLoadedClass();
210     return cl != null ? cl.getClassLoader() : null;
211   }
212
213   /**
214    * Find the first non-system class on the execution stack. A non-system
215    * class is one whose ClassLoader is not equal to
216    * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
217    * will return null in three cases:
218    *
219    * <ul>
220    * <li>All methods on the stack are from system classes</li>
221    * <li>All methods on the stack up to the first "privileged" caller, as
222    *  created by {@link AccessController.doPrivileged(PrivilegedAction)},
223    *  are from system classes</li>
224    * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
225    * </ul>
226    * 
227    * @return the most recent non-system Class on the execution stack
228    * @deprecated use {@link #checkPermission(Permission)} instead
229    */
230   protected Class currentLoadedClass()
231   {
232     int i = classLoaderDepth();
233     return i >= 0 ? getClassContext()[i] : null;
234   }
235
236   /**
237    * Get the depth of a particular class on the execution stack.
238    *
239    * @param className the fully-qualified name to search for
240    * @return the index of the class on the stack, or -1
241    * @deprecated use {@link #checkPermission(Permission)} instead
242    */
243   protected int classDepth(String className)
244   {
245     Class[] c = getClassContext();
246     for (int i = 0; i < c.length; i++)
247       if (className.equals(c[i].getName()))
248         return i;
249     return -1;
250   }
251
252   /**
253    * Get the depth on the execution stack of the most recent non-system class.
254    * A non-system class is one whose ClassLoader is not equal to
255    * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
256    * will return -1 in three cases:
257    *
258    * <ul>
259    * <li>All methods on the stack are from system classes</li>
260    * <li>All methods on the stack up to the first "privileged" caller, as
261    *  created by {@link AccessController.doPrivileged(PrivilegedAction)},
262    *  are from system classes</li>
263    * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
264    * </ul>
265    * 
266    * @return the index of the most recent non-system Class on the stack
267    * @deprecated use {@link #checkPermission(Permission)} instead
268    */
269   protected int classLoaderDepth()
270   {
271     try
272       {
273         checkPermission(new AllPermission());
274       }
275     catch (SecurityException e)
276       {
277         Class[] c = getClassContext();
278         for (int i = 0; i < c.length; i++)
279           if (c[i].getClassLoader() != null)
280             // XXX Check if c[i] is AccessController, or a system class.
281             return i;
282       }
283     return -1;
284   }
285
286   /**
287    * Tell whether the specified class is on the execution stack.
288    *
289    * @param className the fully-qualified name of the class to find
290    * @return whether the specified class is on the execution stack
291    * @deprecated use {@link #checkPermission(Permission)} instead
292    */
293   protected boolean inClass(String className)
294   {
295     return classDepth(className) != -1;
296   }
297
298   /**
299    * Tell whether there is a class loaded with an explicit ClassLoader on
300    * the stack.
301    *
302    * @return whether a class with an explicit ClassLoader is on the stack
303    * @deprecated use {@link #checkPermission(Permission)} instead
304    */
305   protected boolean inClassLoader()
306   {
307     return classLoaderDepth() != -1;
308   }
309
310   /**
311    * Get an implementation-dependent Object that contains enough information
312    * about the current environment to be able to perform standard security
313    * checks later.  This is used by trusted methods that need to verify that
314    * their callers have sufficient access to perform certain operations.
315    *
316    * <p>Currently the only methods that use this are checkRead() and
317    * checkConnect(). The default implementation returns an
318    * <code>AccessControlContext</code>.
319    *
320    * @return a security context
321    * @see #checkConnect(String, int, Object)
322    * @see #checkRead(String, Object)
323    * @see AccessControlContext
324    * @see AccessController#getContext()
325    */
326   public Object getSecurityContext()
327   {
328     return AccessController.getContext();
329   }
330
331   /**
332    * Check if the current thread is allowed to perform an operation that
333    * requires the specified <code>Permission</code>. This defaults to
334    * <code>AccessController.checkPermission</code>.
335    *
336    * @param perm the <code>Permission</code> required
337    * @throws SecurityException if permission is denied
338    * @throws NullPointerException if perm is null
339    * @since 1.2
340    */
341   public void checkPermission(Permission perm)
342   {
343     AccessController.checkPermission(perm);
344   }
345
346   /**
347    * Check if the current thread is allowed to perform an operation that
348    * requires the specified <code>Permission</code>. This is done in a
349    * context previously returned by <code>getSecurityContext()</code>. The
350    * default implementation expects context to be an AccessControlContext,
351    * and it calls <code>AccessControlContext.checkPermission(perm)</code>.
352    *
353    * @param perm the <code>Permission</code> required
354    * @param context a security context
355    * @throws SecurityException if permission is denied, or if context is
356    *         not an AccessControlContext
357    * @throws NullPointerException if perm is null
358    * @see #getSecurityContext()
359    * @see AccessControlContext#checkPermission(Permission)
360    * @since 1.2
361    */
362   public void checkPermission(Permission perm, Object context)
363   {
364     if (! (context instanceof AccessControlContext))
365       throw new SecurityException("Missing context");
366     ((AccessControlContext) context).checkPermission(perm);
367   }
368
369   /**
370    * Check if the current thread is allowed to create a ClassLoader. This
371    * method is called from ClassLoader.ClassLoader(), and checks
372    * <code>RuntimePermission("createClassLoader")</code>. If you override
373    * this, you should call <code>super.checkCreateClassLoader()</code> rather
374    * than throwing an exception.
375    *
376    * @throws SecurityException if permission is denied
377    * @see ClassLoader#ClassLoader()
378    */
379   public void checkCreateClassLoader()
380   {
381     checkPermission(new RuntimePermission("createClassLoader"));
382   }
383
384   /**
385    * Check if the current thread is allowed to modify another Thread. This is
386    * called by Thread.stop(), suspend(), resume(), interrupt(), destroy(),
387    * setPriority(), setName(), and setDaemon(). The default implementation
388    * checks <code>RuntimePermission("modifyThread")</code> on system threads
389    * (ie. threads in ThreadGroup with a null parent), and returns silently on
390    * other threads.
391    *
392    * <p>If you override this, you must do two things. First, call
393    * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
394    * requirements. Second, if the calling thread has
395    * <code>RuntimePermission("modifyThread")</code>, return silently, so that
396    * core classes (the Classpath library!) can modify any thread.
397    *
398    * @param thread the other Thread to check
399    * @throws SecurityException if permission is denied
400    * @throws NullPointerException if thread is null
401    * @see Thread#stop()
402    * @see Thread#suspend()
403    * @see Thread#resume()
404    * @see Thread#setPriority(int)
405    * @see Thread#setName(String)
406    * @see Thread#setDaemon(boolean)
407    */
408   public void checkAccess(Thread thread)
409   {
410     if (thread.getThreadGroup() != null 
411         && thread.getThreadGroup().getParent() != null)
412       checkPermission(new RuntimePermission("modifyThread"));
413   }
414
415   /**
416    * Check if the current thread is allowed to modify a ThreadGroup. This is
417    * called by Thread.Thread() (to add a thread to the ThreadGroup),
418    * ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent),
419    * ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(),
420    * setDaemon(), and setMaxPriority(). The default implementation
421    * checks <code>RuntimePermission("modifyThread")</code> on the system group
422    * (ie. the one with a null parent), and returns silently on other groups.
423    *
424    * <p>If you override this, you must do two things. First, call
425    * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
426    * requirements. Second, if the calling thread has
427    * <code>RuntimePermission("modifyThreadGroup")</code>, return silently,
428    * so that core classes (the Classpath library!) can modify any thread.
429    *
430    * @param g the ThreadGroup to check
431    * @throws SecurityException if permission is denied
432    * @throws NullPointerException if g is null
433    * @see Thread#Thread()
434    * @see ThreadGroup#ThreadGroup()
435    * @see ThreadGroup#stop()
436    * @see ThreadGroup#suspend()
437    * @see ThreadGroup#resume()
438    * @see ThreadGroup#interrupt()
439    * @see ThreadGroup#setDaemon(boolean)
440    * @see ThreadGroup#setMaxPriority(int)
441    */
442   public void checkAccess(ThreadGroup g)
443   {
444     if (g.getParent() != null)
445       checkPermission(new RuntimePermission("modifyThreadGroup"));
446   }
447
448   /**
449    * Check if the current thread is allowed to exit the JVM with the given
450    * status. This method is called from Runtime.exit() and Runtime.halt().
451    * The default implementation checks
452    * <code>RuntimePermission("exitVM")</code>. If you override this, call
453    * <code>super.checkExit</code> rather than throwing an exception.
454    *
455    * @param status the status to exit with
456    * @throws SecurityException if permission is denied
457    * @see Runtime#exit(int)
458    * @see Runtime#halt(int)
459    */
460   public void checkExit(int status)
461   {
462     checkPermission(new RuntimePermission("exitVM"));
463   }
464
465   /**
466    * Check if the current thread is allowed to execute the given program. This
467    * method is called from Runtime.exec(). If the name is an absolute path,
468    * the default implementation checks
469    * <code>FilePermission(program, "execute")</code>, otherwise it checks
470    * <code>FilePermission("&lt;&lt;ALL FILES&gt;&gt;", "execute")</code>. If
471    * you override this, call <code>super.checkExec</code> rather than
472    * throwing an exception.
473    *
474    * @param program the name of the program to exec
475    * @throws SecurityException if permission is denied
476    * @throws NullPointerException if program is null
477    * @see Runtime#exec(String[], String[], File)
478    */
479   public void checkExec(String program)
480   {
481     if (! program.equals(new File(program).getAbsolutePath()))
482       program = "<<ALL FILES>>";
483     checkPermission(new FilePermission(program, "execute"));
484   }
485
486   /**
487    * Check if the current thread is allowed to link in the given native
488    * library. This method is called from Runtime.load() (and hence, by
489    * loadLibrary() as well). The default implementation checks
490    * <code>RuntimePermission("loadLibrary." + filename)</code>. If you
491    * override this, call <code>super.checkLink</code> rather than throwing
492    * an exception.
493    *
494    * @param filename the full name of the library to load
495    * @throws SecurityException if permission is denied
496    * @throws NullPointerException if filename is null
497    * @see Runtime#load(String)
498    */
499   public void checkLink(String filename)
500   {
501     // Use the toString() hack to do the null check.
502     checkPermission(new RuntimePermission("loadLibrary."
503                                           + filename.toString()));
504   }
505
506   /**
507    * Check if the current thread is allowed to read the given file using the
508    * FileDescriptor. This method is called from
509    * FileInputStream.FileInputStream(). The default implementation checks
510    * <code>RuntimePermission("readFileDescriptor")</code>. If you override
511    * this, call <code>super.checkRead</code> rather than throwing an
512    * exception.
513    *
514    * @param desc the FileDescriptor representing the file to access
515    * @throws SecurityException if permission is denied
516    * @throws NullPointerException if desc is null
517    * @see FileInputStream#FileInputStream(FileDescriptor)
518    */
519   public void checkRead(FileDescriptor desc)
520   {
521     if (desc == null)
522       throw new NullPointerException();
523     checkPermission(new RuntimePermission("readFileDescriptor"));
524   }
525
526   /**
527    * Check if the current thread is allowed to read the given file. This
528    * method is called from FileInputStream.FileInputStream(),
529    * RandomAccessFile.RandomAccessFile(), File.exists(), canRead(), isFile(),
530    * isDirectory(), lastModified(), length() and list(). The default
531    * implementation checks <code>FilePermission(filename, "read")</code>. If
532    * you override this, call <code>super.checkRead</code> rather than
533    * throwing an exception.
534    *
535    * @param filename the full name of the file to access
536    * @throws SecurityException if permission is denied
537    * @throws NullPointerException if filename is null
538    * @see File
539    * @see FileInputStream#FileInputStream(String)
540    * @see RandomAccessFile#RandomAccessFile(String)
541    */
542   public void checkRead(String filename)
543   {
544     checkPermission(new FilePermission(filename, "read"));
545   }
546
547   /**
548    * Check if the current thread is allowed to read the given file. using the
549    * given security context. The context must be a result of a previous call
550    * to <code>getSecurityContext()</code>. The default implementation checks
551    * <code>AccessControlContext.checkPermission(new FilePermission(filename,
552    * "read"))</code>. If you override this, call <code>super.checkRead</code>
553    * rather than throwing an exception.
554    *
555    * @param filename the full name of the file to access
556    * @param context the context to determine access for
557    * @throws SecurityException if permission is denied, or if context is
558    *         not an AccessControlContext
559    * @throws NullPointerException if filename is null
560    * @see #getSecurityContext()
561    * @see AccessControlContext#checkPermission(Permission)
562    */
563   public void checkRead(String filename, Object context)
564   {
565     if (! (context instanceof AccessControlContext))
566       throw new SecurityException("Missing context");
567     AccessControlContext ac = (AccessControlContext) context;
568     ac.checkPermission(new FilePermission(filename, "read"));
569   }
570
571   /**
572    * Check if the current thread is allowed to write the given file using the
573    * FileDescriptor. This method is called from
574    * FileOutputStream.FileOutputStream(). The default implementation checks
575    * <code>RuntimePermission("writeFileDescriptor")</code>. If you override
576    * this, call <code>super.checkWrite</code> rather than throwing an
577    * exception.
578    *
579    * @param desc the FileDescriptor representing the file to access
580    * @throws SecurityException if permission is denied
581    * @throws NullPointerException if desc is null
582    * @see FileOutputStream#FileOutputStream(FileDescriptor)
583    */
584   public void checkWrite(FileDescriptor desc)
585   {
586     if (desc == null)
587       throw new NullPointerException();
588     checkPermission(new RuntimePermission("writeFileDescriptor"));
589   }
590
591   /**
592    * Check if the current thread is allowed to write the given file. This
593    * method is called from FileOutputStream.FileOutputStream(),
594    * RandomAccessFile.RandomAccessFile(), File.canWrite(), mkdir(), and
595    * renameTo(). The default implementation checks
596    * <code>FilePermission(filename, "write")</code>. If you override this,
597    * call <code>super.checkWrite</code> rather than throwing an exception.
598    *
599    * @param filename the full name of the file to access
600    * @throws SecurityException if permission is denied
601    * @throws NullPointerException if filename is null
602    * @see File
603    * @see File#canWrite()
604    * @see File#mkdir()
605    * @see File#renameTo()
606    * @see FileOutputStream#FileOutputStream(String)
607    * @see RandomAccessFile#RandomAccessFile(String)
608    */
609   public void checkWrite(String filename)
610   {
611     checkPermission(new FilePermission(filename, "write"));
612   }
613
614   /**
615    * Check if the current thread is allowed to delete the given file. This
616    * method is called from File.delete(). The default implementation checks
617    * <code>FilePermission(filename, "delete")</code>. If you override this,
618    * call <code>super.checkDelete</code> rather than throwing an exception.
619    *
620    * @param filename the full name of the file to delete
621    * @throws SecurityException if permission is denied
622    * @throws NullPointerException if filename is null
623    * @see File#delete()
624    */
625   public void checkDelete(String filename)
626   {
627     checkPermission(new FilePermission(filename, "delete"));
628   }
629
630   /**
631    * Check if the current thread is allowed to connect to a given host on a
632    * given port. This method is called from Socket.Socket(). A port number
633    * of -1 indicates the caller is attempting to determine an IP address, so
634    * the default implementation checks
635    * <code>SocketPermission(host, "resolve")</code>. Otherwise, the default
636    * implementation checks
637    * <code>SocketPermission(host + ":" + port, "connect")</code>. If you
638    * override this, call <code>super.checkConnect</code> rather than throwing
639    * an exception.
640    *
641    * @param host the host to connect to
642    * @param port the port to connect on
643    * @throws SecurityException if permission is denied
644    * @throws NullPointerException if host is null
645    * @see Socket#Socket()
646    */
647   public void checkConnect(String host, int port)
648   {
649     if (port == -1)
650       checkPermission(new SocketPermission(host, "resolve"));
651     else
652       // Use the toString() hack to do the null check.
653       checkPermission(new SocketPermission(host.toString() + ":" + port,
654                                            "connect"));
655   }
656
657   /**
658    * Check if the current thread is allowed to connect to a given host on a
659    * given port, using the given security context. The context must be a
660    * result of a previous call to <code>getSecurityContext</code>. A port
661    * number of -1 indicates the caller is attempting to determine an IP
662    * address, so the default implementation checks
663    * <code>AccessControlContext.checkPermission(new SocketPermission(host,
664    * "resolve"))</code>. Otherwise, the default implementation checks
665    * <code>AccessControlContext.checkPermission(new SocketPermission(host
666    * + ":" + port, "connect"))</code>. If you override this, call
667    * <code>super.checkConnect</code> rather than throwing an exception.
668    *
669    * @param host the host to connect to
670    * @param port the port to connect on
671    * @param context the context to determine access for
672    *
673    * @throws SecurityException if permission is denied, or if context is
674    *         not an AccessControlContext
675    * @throws NullPointerException if host is null
676    *
677    * @see #getSecurityContext()
678    * @see AccessControlContext#checkPermission(Permission)
679    */
680   public void checkConnect(String host, int port, Object context)
681   {
682     if (! (context instanceof AccessControlContext))
683       throw new SecurityException("Missing context");
684     AccessControlContext ac = (AccessControlContext) context;
685     if (port == -1)
686       ac.checkPermission(new SocketPermission(host, "resolve"));
687     else
688       // Use the toString() hack to do the null check.
689       ac.checkPermission(new SocketPermission(host.toString() + ":" + port,
690                                               "connect"));
691   }
692
693   /**
694    * Check if the current thread is allowed to listen to a specific port for
695    * data. This method is called by ServerSocket.ServerSocket(). The default
696    * implementation checks
697    * <code>SocketPermission("localhost:" + (port == 0 ? "1024-" : "" + port),
698    * "listen")</code>. If you override this, call
699    * <code>super.checkListen</code> rather than throwing an exception.
700    *
701    * @param port the port to listen on
702    * @throws SecurityException if permission is denied
703    * @see ServerSocket#ServerSocket(int)
704    */
705   public void checkListen(int port)
706   {
707     checkPermission(new SocketPermission("localhost:"
708                                          + (port == 0 ? "1024-" : "" +port),
709                                          "listen"));
710   }
711
712   /**
713    * Check if the current thread is allowed to accept a connection from a
714    * particular host on a particular port. This method is called by
715    * ServerSocket.implAccept(). The default implementation checks
716    * <code>SocketPermission(host + ":" + port, "accept")</code>. If you
717    * override this, call <code>super.checkAccept</code> rather than throwing
718    * an exception.
719    *
720    * @param host the host which wishes to connect
721    * @param port the port the connection will be on
722    * @throws SecurityException if permission is denied
723    * @throws NullPointerException if host is null
724    * @see ServerSocket#accept()
725    */
726   public void checkAccept(String host, int port)
727   {
728     // Use the toString() hack to do the null check.
729     checkPermission(new SocketPermission(host.toString() + ":" + port,
730                                          "accept"));
731   }
732
733   /**
734    * Check if the current thread is allowed to read and write multicast to
735    * a particular address. The default implementation checks
736    * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
737    * If you override this, call <code>super.checkMulticast</code> rather than
738    * throwing an exception.
739    *
740    * @param addr the address to multicast to
741    * @throws SecurityException if permission is denied
742    * @throws NullPointerException if host is null
743    * @since 1.1
744    */
745   public void checkMulticast(InetAddress addr)
746   {
747     checkPermission(new SocketPermission(addr.getHostAddress(),
748                                          "accept,connect"));
749   }
750
751   /**
752    *Check if the current thread is allowed to read and write multicast to
753    * a particular address with a particular ttl (time-to-live) value. The
754    * default implementation ignores ttl, and checks
755    * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
756    * If you override this, call <code>super.checkMulticast</code> rather than
757    * throwing an exception.
758    *
759    * @param addr the address to multicast to
760    * @param ttl value in use for multicast send
761    * @throws SecurityException if permission is denied
762    * @throws NullPointerException if host is null
763    * @since 1.1
764    * @deprecated use {@link #checkPermission(Permission)} instead
765    */
766   public void checkMulticast(InetAddress addr, byte ttl)
767   {
768     checkPermission(new SocketPermission(addr.getHostAddress(),
769                                          "accept,connect"));
770   }
771
772   /**
773    * Check if the current thread is allowed to read or write all the system
774    * properties at once. This method is called by System.getProperties()
775    * and setProperties(). The default implementation checks
776    * <code>PropertyPermission("*", "read,write")</code>. If you override
777    * this, call <code>super.checkPropertiesAccess</code> rather than
778    * throwing an exception.
779    *
780    * @throws SecurityException if permission is denied
781    * @see System#getProperties()
782    * @see System#setProperties(Properties)
783    */
784   public void checkPropertiesAccess()
785   {
786     checkPermission(new PropertyPermission("*", "read,write"));
787   }
788
789   /**
790    * Check if the current thread is allowed to read a particular system
791    * property (writes are checked directly via checkPermission). This method
792    * is called by System.getProperty() and setProperty(). The default
793    * implementation checks <code>PropertyPermission(key, "read")</code>. If
794    * you override this, call <code>super.checkPropertyAccess</code> rather
795    * than throwing an exception.
796    *
797    * @param key the key of the property to check
798    *
799    * @throws SecurityException if permission is denied
800    * @throws NullPointerException if key is null
801    * @throws IllegalArgumentException if key is ""
802    *
803    * @see System#getProperty(String)
804    */
805   public void checkPropertyAccess(String key)
806   {
807     checkPermission(new PropertyPermission(key, "read"));
808   }
809
810   /**
811    * Check if the current thread is allowed to create a top-level window. If
812    * it is not, the operation should still go through, but some sort of
813    * nonremovable warning should be placed on the window to show that it
814    * is untrusted. This method is called by Window.Window(). The default
815    * implementation checks
816    * <code>AWTPermission("showWindowWithoutWarningBanner")</code>, and returns
817    * true if no exception was thrown. If you override this, use
818    * <code>return super.checkTopLevelWindow</code> rather than returning
819    * false.
820    *
821    * @param window the window to create
822    * @return true if there is permission to show the window without warning
823    * @throws NullPointerException if window is null
824    * @see Window#Window(Frame)
825    */
826   public boolean checkTopLevelWindow(Object window)
827   {
828     if (window == null)
829       throw new NullPointerException();
830     try
831       {
832         checkPermission(new AWTPermission("showWindowWithoutWarningBanner"));
833         return true;
834       }
835     catch (SecurityException e)
836       {
837         return false;
838       }
839   }
840
841   /**
842    * Check if the current thread is allowed to create a print job. This
843    * method is called by Toolkit.getPrintJob(). The default implementation
844    * checks <code>RuntimePermission("queuePrintJob")</code>. If you override
845    * this, call <code>super.checkPrintJobAccess</code> rather than throwing
846    * an exception.
847    *
848    * @throws SecurityException if permission is denied
849    * @see Toolkit#getPrintJob(Frame, String, Properties)
850    * @since 1.1
851    */
852   public void checkPrintJobAccess()
853   {
854     checkPermission(new RuntimePermission("queuePrintJob"));
855   }
856
857   /**
858    * Check if the current thread is allowed to use the system clipboard. This
859    * method is called by Toolkit.getSystemClipboard(). The default
860    * implementation checks <code>AWTPermission("accessClipboard")</code>. If
861    * you override this, call <code>super.checkSystemClipboardAccess</code>
862    * rather than throwing an exception.
863    *
864    * @throws SecurityException if permission is denied
865    * @see Toolkit#getSystemClipboard()
866    * @since 1.1
867    */
868   public void checkSystemClipboardAccess()
869   {
870     checkPermission(new AWTPermission("accessClipboard"));
871   }
872
873   /**
874    * Check if the current thread is allowed to use the AWT event queue. This
875    * method is called by Toolkit.getSystemEventQueue(). The default
876    * implementation checks <code>AWTPermission("accessEventQueue")</code>.
877    * you override this, call <code>super.checkAwtEventQueueAccess</code>
878    * rather than throwing an exception.
879    *
880    * @throws SecurityException if permission is denied
881    * @see Toolkit#getSystemEventQueue()
882    * @since 1.1
883    */
884   public void checkAwtEventQueueAccess()
885   {
886     checkPermission(new AWTPermission("accessEventQueue"));
887   }
888
889   /**
890    * Check if the current thread is allowed to access the specified package
891    * at all. This method is called by ClassLoader.loadClass() in user-created
892    * ClassLoaders. The default implementation gets a list of all restricted
893    * packages, via <code>Security.getProperty("package.access")</code>. Then,
894    * if packageName starts with or equals any restricted package, it checks
895    * <code>RuntimePermission("accessClassInPackage." + packageName)</code>.
896    * If you override this, you should call
897    * <code>super.checkPackageAccess</code> before doing anything else.
898    *
899    * @param packageName the package name to check access to
900    * @throws SecurityException if permission is denied
901    * @throws NullPointerException if packageName is null
902    * @see ClassLoader#loadClass(String, boolean)
903    * @see Security#getProperty(String)
904    */
905   public void checkPackageAccess(String packageName)
906   {
907     checkPackageList(packageName, "package.access", "accessClassInPackage.");
908   }
909
910   /**
911    * Check if the current thread is allowed to define a class into the
912    * specified package. This method is called by ClassLoader.loadClass() in
913    * user-created ClassLoaders. The default implementation gets a list of all
914    * restricted packages, via
915    * <code>Security.getProperty("package.definition")</code>. Then, if
916    * packageName starts with or equals any restricted package, it checks
917    * <code>RuntimePermission("defineClassInPackage." + packageName)</code>.
918    * If you override this, you should call
919    * <code>super.checkPackageDefinition</code> before doing anything else.
920    *
921    * @param packageName the package name to check access to
922    * @throws SecurityException if permission is denied
923    * @throws NullPointerException if packageName is null
924    * @see ClassLoader#loadClass(String, boolean)
925    * @see Security#getProperty(String)
926    */
927   public void checkPackageDefinition(String packageName)
928   {
929     checkPackageList(packageName, "package.definition", "defineClassInPackage.");
930   }
931
932   /**
933    * Check if the current thread is allowed to set the current socket factory.
934    * This method is called by Socket.setSocketImplFactory(),
935    * ServerSocket.setSocketFactory(), and URL.setURLStreamHandlerFactory().
936    * The default implementation checks
937    * <code>RuntimePermission("setFactory")</code>. If you override this, call
938    * <code>super.checkSetFactory</code> rather than throwing an exception.
939    *
940    * @throws SecurityException if permission is denied
941    * @see Socket#setSocketImplFactory(SocketImplFactory)
942    * @see ServerSocket#setSocketFactory(SocketImplFactory)
943    * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
944    */
945   public void checkSetFactory()
946   {
947     checkPermission(new RuntimePermission("setFactory"));
948   }
949
950   /**
951    * Check if the current thread is allowed to get certain types of Methods,
952    * Fields and Constructors from a Class object. This method is called by
953    * Class.getMethod[s](), Class.getField[s](), Class.getConstructor[s],
954    * Class.getDeclaredMethod[s](), Class.getDeclaredField[s](), and
955    * Class.getDeclaredConstructor[s](). The default implementation allows
956    * PUBLIC access, and access to classes defined by the same classloader as
957    * the code performing the reflection. Otherwise, it checks
958    * <code>RuntimePermission("accessDeclaredMembers")</code>. If you override
959    * this, do not call <code>super.checkMemberAccess</code>, as this would
960    * mess up the stack depth check that determines the ClassLoader requesting
961    * the access.
962    *
963    * @param c the Class to check
964    * @param memberType either DECLARED or PUBLIC
965    * @throws SecurityException if permission is denied, including when
966    *         memberType is not DECLARED or PUBLIC
967    * @throws NullPointerException if c is null
968    * @see Class
969    * @see Member#DECLARED
970    * @see Member#PUBLIC
971    * @since 1.1
972    */
973   public void checkMemberAccess(Class c, int memberType)
974   {
975     if (c == null)
976       throw new NullPointerException();
977     if (memberType == Member.PUBLIC)
978       return;
979     // XXX Allow access to classes created by same classloader before next
980     // check.
981     checkPermission(new RuntimePermission("accessDeclaredMembers"));
982   }
983
984   /**
985    * Test whether a particular security action may be taken. The default
986    * implementation checks <code>SecurityPermission(action)</code>. If you
987    * override this, call <code>super.checkSecurityAccess</code> rather than
988    * throwing an exception.
989    *
990    * @param action the desired action to take
991    * @throws SecurityException if permission is denied
992    * @throws NullPointerException if action is null
993    * @throws IllegalArgumentException if action is ""
994    * @since 1.1
995    */
996   public void checkSecurityAccess(String action)
997   {
998     checkPermission(new SecurityPermission(action));
999   }
1000
1001   /**
1002    * Get the ThreadGroup that a new Thread should belong to by default. Called
1003    * by Thread.Thread(). The default implementation returns the current
1004    * ThreadGroup of the current Thread. <STRONG>Spec Note:</STRONG> it is not
1005    * clear whether the new Thread is guaranteed to pass the
1006    * checkAccessThreadGroup() test when using this ThreadGroup, but I presume
1007    * so.
1008    *
1009    * @return the ThreadGroup to put the new Thread into
1010    * @since 1.1
1011    */
1012   public ThreadGroup getThreadGroup()
1013   {
1014     return Thread.currentThread().getThreadGroup();
1015   }
1016
1017   /**
1018    * Helper that checks a comma-separated list of restricted packages, from
1019    * <code>Security.getProperty("package.definition")</code>, for the given
1020    * package access permission. If packageName starts with or equals any
1021    * restricted package, it checks
1022    * <code>RuntimePermission(permission + packageName)</code>.
1023    *
1024    * @param packageName the package name to check access to
1025    * @param restriction "package.access" or "package.definition"
1026    * @param permission the base permission, including the '.'
1027    * @throws SecurityException if permission is denied
1028    * @throws NullPointerException if packageName is null
1029    * @see #checkPackageAccess(String)
1030    * @see #checkPackageDefinition(String)
1031    */
1032   void checkPackageList(String packageName, final String restriction,
1033                         String permission)
1034   {
1035     if (packageName == null)
1036       throw new NullPointerException();
1037
1038     String list = (String)AccessController.doPrivileged(new PrivilegedAction()
1039       {
1040         public Object run()
1041         {
1042           return Security.getProperty(restriction);
1043         }
1044       });
1045
1046     if (list == null || list.equals(""))
1047       return;
1048
1049     String packageNamePlusDot = packageName + ".";
1050
1051     StringTokenizer st = new StringTokenizer(list, ",");
1052     while (st.hasMoreTokens())
1053       {
1054         if (packageNamePlusDot.startsWith(st.nextToken()))
1055           {
1056             Permission p = new RuntimePermission(permission + packageName);
1057             checkPermission(p);
1058             return;
1059           }
1060       }
1061   }
1062 }