OSDN Git Service

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