| /* SecurityManager.java -- security checks for privileged actions |
| Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 |
| Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package java.lang; |
| |
| import java.awt.AWTPermission; |
| import java.io.File; |
| import java.io.FileDescriptor; |
| import java.io.FilePermission; |
| import java.lang.reflect.Member; |
| import java.net.InetAddress; |
| import java.net.SocketPermission; |
| import java.security.AccessController; |
| import java.security.AccessControlContext; |
| import java.security.AllPermission; |
| import java.security.Permission; |
| import java.security.PrivilegedAction; |
| import java.security.Security; |
| import java.security.SecurityPermission; |
| import java.util.PropertyPermission; |
| import java.util.StringTokenizer; |
| |
| /** |
| * SecurityManager is a class you can extend to create your own Java |
| * security policy. By default, there is no SecurityManager installed in |
| * 1.1, which means that all things are permitted to all people. The security |
| * manager, if set, is consulted before doing anything with potentially |
| * dangerous results, and throws a <code>SecurityException</code> if the |
| * action is forbidden. |
| * |
| * <p>A typical check is as follows, just before the dangerous operation:<br> |
| * <pre> |
| * SecurityManager sm = System.getSecurityManager(); |
| * if (sm != null) |
| * sm.checkABC(<em>argument</em>, ...); |
| * </pre> |
| * Note that this is thread-safe, by caching the security manager in a local |
| * variable rather than risking a NullPointerException if the mangager is |
| * changed between the check for null and before the permission check. |
| * |
| * <p>The special method <code>checkPermission</code> is a catchall, and |
| * the default implementation calls |
| * <code>AccessController.checkPermission</code>. In fact, all the other |
| * methods default to calling checkPermission. |
| * |
| * <p>Sometimes, the security check needs to happen from a different context, |
| * such as when called from a worker thread. In such cases, use |
| * <code>getSecurityContext</code> to take a snapshot that can be passed |
| * to the worker thread:<br> |
| * <pre> |
| * Object context = null; |
| * SecurityManager sm = System.getSecurityManager(); |
| * if (sm != null) |
| * context = sm.getSecurityContext(); // defaults to an AccessControlContext |
| * // now, in worker thread |
| * if (sm != null) |
| * sm.checkPermission(permission, context); |
| * </pre> |
| * |
| * <p>Permissions fall into these categories: File, Socket, Net, Security, |
| * Runtime, Property, AWT, Reflect, and Serializable. Each of these |
| * permissions have a property naming convention, that follows a hierarchical |
| * naming convention, to make it easy to grant or deny several permissions |
| * at once. Some permissions also take a list of permitted actions, such |
| * as "read" or "write", to fine-tune control even more. The permission |
| * <code>java.security.AllPermission</code> grants all permissions. |
| * |
| * <p>The default methods in this class deny all things to all people. You |
| * must explicitly grant permission for anything you want to be legal when |
| * subclassing this class. |
| * |
| * @author John Keiser |
| * @author Eric Blake (ebb9@email.byu.edu) |
| * @see ClassLoader |
| * @see SecurityException |
| * @see #checkTopLevelWindow(Object) |
| * @see System#getSecurityManager() |
| * @see System#setSecurityManager(SecurityManager) |
| * @see AccessController |
| * @see AccessControlContext |
| * @see AccessControlException |
| * @see Permission |
| * @see BasicPermission |
| * @see java.io.FilePermission |
| * @see java.net.SocketPermission |
| * @see java.util.PropertyPermission |
| * @see RuntimePermission |
| * @see java.awt.AWTPermission |
| * @see Policy |
| * @see SecurityPermission |
| * @see ProtectionDomain |
| * @since 1.0 |
| * @status still missing 1.4 functionality |
| */ |
| public class SecurityManager |
| { |
| /** |
| * The current security manager. This is located here instead of in |
| * System, to avoid security problems, as well as bootstrap issues. |
| * Make sure to access it in a thread-safe manner; it is package visible |
| * to avoid overhead in java.lang. |
| */ |
| static volatile SecurityManager current; |
| |
| /** |
| * Tells whether or not the SecurityManager is currently performing a |
| * security check. |
| * @deprecated Use {@link #checkPermission(Permission)} instead. |
| */ |
| protected boolean inCheck; |
| |
| /** |
| * Construct a new security manager. There may be a security check, of |
| * <code>RuntimePermission("createSecurityManager")</code>. |
| * |
| * @throws SecurityException if permission is denied |
| */ |
| public SecurityManager() |
| { |
| SecurityManager sm = System.getSecurityManager(); |
| if (sm != null) |
| sm.checkPermission(new RuntimePermission("createSecurityManager")); |
| } |
| |
| /** |
| * Tells whether or not the SecurityManager is currently performing a |
| * security check. |
| * |
| * @return true if the SecurityManager is in a security check |
| * @see #inCheck |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| public boolean getInCheck() |
| { |
| return inCheck; |
| } |
| |
| /** |
| * Get a list of all the classes currently executing methods on the Java |
| * stack. getClassContext()[0] is the currently executing method (ie. the |
| * class that CALLED getClassContext, not SecurityManager). |
| * |
| * @return an array of classes on the Java execution stack |
| */ |
| protected Class[] getClassContext() |
| { |
| return VMSecurityManager.getClassContext(SecurityManager.class); |
| } |
| |
| /** |
| * Find the ClassLoader of the first non-system class on the execution |
| * stack. A non-system class is one whose ClassLoader is not equal to |
| * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This |
| * will return null in three cases: |
| * |
| * <ul> |
| * <li>All methods on the stack are from system classes</li> |
| * <li>All methods on the stack up to the first "privileged" caller, as |
| * created by {@link AccessController#doPrivileged(PrivilegedAction)}, |
| * are from system classes</li> |
| * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> |
| * </ul> |
| * |
| * @return the most recent non-system ClassLoader on the execution stack |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected ClassLoader currentClassLoader() |
| { |
| return VMSecurityManager.currentClassLoader(SecurityManager.class); |
| } |
| |
| /** |
| * Find the first non-system class on the execution stack. A non-system |
| * class is one whose ClassLoader is not equal to |
| * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This |
| * will return null in three cases: |
| * |
| * <ul> |
| * <li>All methods on the stack are from system classes</li> |
| * <li>All methods on the stack up to the first "privileged" caller, as |
| * created by {@link AccessController#doPrivileged(PrivilegedAction)}, |
| * are from system classes</li> |
| * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> |
| * </ul> |
| * |
| * @return the most recent non-system Class on the execution stack |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected Class currentLoadedClass() |
| { |
| int i = classLoaderDepth(); |
| return i >= 0 ? getClassContext()[i] : null; |
| } |
| |
| /** |
| * Get the depth of a particular class on the execution stack. |
| * |
| * @param className the fully-qualified name to search for |
| * @return the index of the class on the stack, or -1 |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected int classDepth(String className) |
| { |
| Class[] c = getClassContext(); |
| for (int i = 0; i < c.length; i++) |
| if (className.equals(c[i].getName())) |
| return i; |
| return -1; |
| } |
| |
| /** |
| * Get the depth on the execution stack of the most recent non-system class. |
| * A non-system class is one whose ClassLoader is not equal to |
| * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This |
| * will return -1 in three cases: |
| * |
| * <ul> |
| * <li>All methods on the stack are from system classes</li> |
| * <li>All methods on the stack up to the first "privileged" caller, as |
| * created by {@link AccessController#doPrivileged(PrivilegedAction)}, |
| * are from system classes</li> |
| * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> |
| * </ul> |
| * |
| * @return the index of the most recent non-system Class on the stack |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected int classLoaderDepth() |
| { |
| try |
| { |
| checkPermission(new AllPermission()); |
| } |
| catch (SecurityException e) |
| { |
| Class[] c = getClassContext(); |
| for (int i = 0; i < c.length; i++) |
| if (c[i].getClassLoader() != null) |
| // XXX Check if c[i] is AccessController, or a system class. |
| return i; |
| } |
| return -1; |
| } |
| |
| /** |
| * Tell whether the specified class is on the execution stack. |
| * |
| * @param className the fully-qualified name of the class to find |
| * @return whether the specified class is on the execution stack |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected boolean inClass(String className) |
| { |
| return classDepth(className) != -1; |
| } |
| |
| /** |
| * Tell whether there is a class loaded with an explicit ClassLoader on |
| * the stack. |
| * |
| * @return whether a class with an explicit ClassLoader is on the stack |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| protected boolean inClassLoader() |
| { |
| return classLoaderDepth() != -1; |
| } |
| |
| /** |
| * Get an implementation-dependent Object that contains enough information |
| * about the current environment to be able to perform standard security |
| * checks later. This is used by trusted methods that need to verify that |
| * their callers have sufficient access to perform certain operations. |
| * |
| * <p>Currently the only methods that use this are checkRead() and |
| * checkConnect(). The default implementation returns an |
| * <code>AccessControlContext</code>. |
| * |
| * @return a security context |
| * @see #checkConnect(String, int, Object) |
| * @see #checkRead(String, Object) |
| * @see AccessControlContext |
| * @see AccessController#getContext() |
| */ |
| public Object getSecurityContext() |
| { |
| return AccessController.getContext(); |
| } |
| |
| /** |
| * Check if the current thread is allowed to perform an operation that |
| * requires the specified <code>Permission</code>. This defaults to |
| * <code>AccessController.checkPermission</code>. |
| * |
| * @param perm the <code>Permission</code> required |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if perm is null |
| * @since 1.2 |
| */ |
| public void checkPermission(Permission perm) |
| { |
| AccessController.checkPermission(perm); |
| } |
| |
| /** |
| * Check if the current thread is allowed to perform an operation that |
| * requires the specified <code>Permission</code>. This is done in a |
| * context previously returned by <code>getSecurityContext()</code>. The |
| * default implementation expects context to be an AccessControlContext, |
| * and it calls <code>AccessControlContext.checkPermission(perm)</code>. |
| * |
| * @param perm the <code>Permission</code> required |
| * @param context a security context |
| * @throws SecurityException if permission is denied, or if context is |
| * not an AccessControlContext |
| * @throws NullPointerException if perm is null |
| * @see #getSecurityContext() |
| * @see AccessControlContext#checkPermission(Permission) |
| * @since 1.2 |
| */ |
| public void checkPermission(Permission perm, Object context) |
| { |
| if (! (context instanceof AccessControlContext)) |
| throw new SecurityException("Missing context"); |
| ((AccessControlContext) context).checkPermission(perm); |
| } |
| |
| /** |
| * Check if the current thread is allowed to create a ClassLoader. This |
| * method is called from ClassLoader.ClassLoader(), and checks |
| * <code>RuntimePermission("createClassLoader")</code>. If you override |
| * this, you should call <code>super.checkCreateClassLoader()</code> rather |
| * than throwing an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see ClassLoader#ClassLoader() |
| */ |
| public void checkCreateClassLoader() |
| { |
| checkPermission(new RuntimePermission("createClassLoader")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to modify another Thread. This is |
| * called by Thread.stop(), suspend(), resume(), interrupt(), destroy(), |
| * setPriority(), setName(), and setDaemon(). The default implementation |
| * checks <code>RuntimePermission("modifyThread")</code> on system threads |
| * (ie. threads in ThreadGroup with a null parent), and returns silently on |
| * other threads. |
| * |
| * <p>If you override this, you must do two things. First, call |
| * <code>super.checkAccess(t)</code>, to make sure you are not relaxing |
| * requirements. Second, if the calling thread has |
| * <code>RuntimePermission("modifyThread")</code>, return silently, so that |
| * core classes (the Classpath library!) can modify any thread. |
| * |
| * @param thread the other Thread to check |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if thread is null |
| * @see Thread#stop() |
| * @see Thread#suspend() |
| * @see Thread#resume() |
| * @see Thread#setPriority(int) |
| * @see Thread#setName(String) |
| * @see Thread#setDaemon(boolean) |
| */ |
| public void checkAccess(Thread thread) |
| { |
| if (thread.getThreadGroup() != null |
| && thread.getThreadGroup().getParent() == null) |
| checkPermission(new RuntimePermission("modifyThread")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to modify a ThreadGroup. This is |
| * called by Thread.Thread() (to add a thread to the ThreadGroup), |
| * ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent), |
| * ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(), |
| * setDaemon(), and setMaxPriority(). The default implementation |
| * checks <code>RuntimePermission("modifyThread")</code> on the system group |
| * (ie. the one with a null parent), and returns silently on other groups. |
| * |
| * <p>If you override this, you must do two things. First, call |
| * <code>super.checkAccess(t)</code>, to make sure you are not relaxing |
| * requirements. Second, if the calling thread has |
| * <code>RuntimePermission("modifyThreadGroup")</code>, return silently, |
| * so that core classes (the Classpath library!) can modify any thread. |
| * |
| * @param g the ThreadGroup to check |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if g is null |
| * @see Thread#Thread() |
| * @see ThreadGroup#ThreadGroup(String) |
| * @see ThreadGroup#stop() |
| * @see ThreadGroup#suspend() |
| * @see ThreadGroup#resume() |
| * @see ThreadGroup#interrupt() |
| * @see ThreadGroup#setDaemon(boolean) |
| * @see ThreadGroup#setMaxPriority(int) |
| */ |
| public void checkAccess(ThreadGroup g) |
| { |
| if (g.getParent() == null) |
| checkPermission(new RuntimePermission("modifyThreadGroup")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to exit the JVM with the given |
| * status. This method is called from Runtime.exit() and Runtime.halt(). |
| * The default implementation checks |
| * <code>RuntimePermission("exitVM")</code>. If you override this, call |
| * <code>super.checkExit</code> rather than throwing an exception. |
| * |
| * @param status the status to exit with |
| * @throws SecurityException if permission is denied |
| * @see Runtime#exit(int) |
| * @see Runtime#halt(int) |
| */ |
| public void checkExit(int status) |
| { |
| checkPermission(new RuntimePermission("exitVM")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to execute the given program. This |
| * method is called from Runtime.exec(). If the name is an absolute path, |
| * the default implementation checks |
| * <code>FilePermission(program, "execute")</code>, otherwise it checks |
| * <code>FilePermission("<<ALL FILES>>", "execute")</code>. If |
| * you override this, call <code>super.checkExec</code> rather than |
| * throwing an exception. |
| * |
| * @param program the name of the program to exec |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if program is null |
| * @see Runtime#exec(String[], String[], File) |
| */ |
| public void checkExec(String program) |
| { |
| if (! program.equals(new File(program).getAbsolutePath())) |
| program = "<<ALL FILES>>"; |
| checkPermission(new FilePermission(program, "execute")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to link in the given native |
| * library. This method is called from Runtime.load() (and hence, by |
| * loadLibrary() as well). The default implementation checks |
| * <code>RuntimePermission("loadLibrary." + filename)</code>. If you |
| * override this, call <code>super.checkLink</code> rather than throwing |
| * an exception. |
| * |
| * @param filename the full name of the library to load |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if filename is null |
| * @see Runtime#load(String) |
| */ |
| public void checkLink(String filename) |
| { |
| // Use the toString() hack to do the null check. |
| checkPermission(new RuntimePermission("loadLibrary." |
| + filename.toString())); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read the given file using the |
| * FileDescriptor. This method is called from |
| * FileInputStream.FileInputStream(). The default implementation checks |
| * <code>RuntimePermission("readFileDescriptor")</code>. If you override |
| * this, call <code>super.checkRead</code> rather than throwing an |
| * exception. |
| * |
| * @param desc the FileDescriptor representing the file to access |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if desc is null |
| * @see FileInputStream#FileInputStream(FileDescriptor) |
| */ |
| public void checkRead(FileDescriptor desc) |
| { |
| if (desc == null) |
| throw new NullPointerException(); |
| checkPermission(new RuntimePermission("readFileDescriptor")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read the given file. This |
| * method is called from FileInputStream.FileInputStream(), |
| * RandomAccessFile.RandomAccessFile(), File.exists(), canRead(), isFile(), |
| * isDirectory(), lastModified(), length() and list(). The default |
| * implementation checks <code>FilePermission(filename, "read")</code>. If |
| * you override this, call <code>super.checkRead</code> rather than |
| * throwing an exception. |
| * |
| * @param filename the full name of the file to access |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if filename is null |
| * @see File |
| * @see FileInputStream#FileInputStream(String) |
| * @see RandomAccessFile#RandomAccessFile(String, String) |
| */ |
| public void checkRead(String filename) |
| { |
| checkPermission(new FilePermission(filename, "read")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read the given file. using the |
| * given security context. The context must be a result of a previous call |
| * to <code>getSecurityContext()</code>. The default implementation checks |
| * <code>AccessControlContext.checkPermission(new FilePermission(filename, |
| * "read"))</code>. If you override this, call <code>super.checkRead</code> |
| * rather than throwing an exception. |
| * |
| * @param filename the full name of the file to access |
| * @param context the context to determine access for |
| * @throws SecurityException if permission is denied, or if context is |
| * not an AccessControlContext |
| * @throws NullPointerException if filename is null |
| * @see #getSecurityContext() |
| * @see AccessControlContext#checkPermission(Permission) |
| */ |
| public void checkRead(String filename, Object context) |
| { |
| if (! (context instanceof AccessControlContext)) |
| throw new SecurityException("Missing context"); |
| AccessControlContext ac = (AccessControlContext) context; |
| ac.checkPermission(new FilePermission(filename, "read")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to write the given file using the |
| * FileDescriptor. This method is called from |
| * FileOutputStream.FileOutputStream(). The default implementation checks |
| * <code>RuntimePermission("writeFileDescriptor")</code>. If you override |
| * this, call <code>super.checkWrite</code> rather than throwing an |
| * exception. |
| * |
| * @param desc the FileDescriptor representing the file to access |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if desc is null |
| * @see FileOutputStream#FileOutputStream(FileDescriptor) |
| */ |
| public void checkWrite(FileDescriptor desc) |
| { |
| if (desc == null) |
| throw new NullPointerException(); |
| checkPermission(new RuntimePermission("writeFileDescriptor")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to write the given file. This |
| * method is called from FileOutputStream.FileOutputStream(), |
| * RandomAccessFile.RandomAccessFile(), File.canWrite(), mkdir(), and |
| * renameTo(). The default implementation checks |
| * <code>FilePermission(filename, "write")</code>. If you override this, |
| * call <code>super.checkWrite</code> rather than throwing an exception. |
| * |
| * @param filename the full name of the file to access |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if filename is null |
| * @see File |
| * @see File#canWrite() |
| * @see File#mkdir() |
| * @see File#renameTo(File) |
| * @see FileOutputStream#FileOutputStream(String) |
| * @see RandomAccessFile#RandomAccessFile(String, String) |
| */ |
| public void checkWrite(String filename) |
| { |
| checkPermission(new FilePermission(filename, "write")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to delete the given file. This |
| * method is called from File.delete(). The default implementation checks |
| * <code>FilePermission(filename, "delete")</code>. If you override this, |
| * call <code>super.checkDelete</code> rather than throwing an exception. |
| * |
| * @param filename the full name of the file to delete |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if filename is null |
| * @see File#delete() |
| */ |
| public void checkDelete(String filename) |
| { |
| checkPermission(new FilePermission(filename, "delete")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to connect to a given host on a |
| * given port. This method is called from Socket.Socket(). A port number |
| * of -1 indicates the caller is attempting to determine an IP address, so |
| * the default implementation checks |
| * <code>SocketPermission(host, "resolve")</code>. Otherwise, the default |
| * implementation checks |
| * <code>SocketPermission(host + ":" + port, "connect")</code>. If you |
| * override this, call <code>super.checkConnect</code> rather than throwing |
| * an exception. |
| * |
| * @param host the host to connect to |
| * @param port the port to connect on |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if host is null |
| * @see Socket#Socket() |
| */ |
| public void checkConnect(String host, int port) |
| { |
| if (port == -1) |
| checkPermission(new SocketPermission(host, "resolve")); |
| else |
| // Use the toString() hack to do the null check. |
| checkPermission(new SocketPermission(host.toString() + ":" + port, |
| "connect")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to connect to a given host on a |
| * given port, using the given security context. The context must be a |
| * result of a previous call to <code>getSecurityContext</code>. A port |
| * number of -1 indicates the caller is attempting to determine an IP |
| * address, so the default implementation checks |
| * <code>AccessControlContext.checkPermission(new SocketPermission(host, |
| * "resolve"))</code>. Otherwise, the default implementation checks |
| * <code>AccessControlContext.checkPermission(new SocketPermission(host |
| * + ":" + port, "connect"))</code>. If you override this, call |
| * <code>super.checkConnect</code> rather than throwing an exception. |
| * |
| * @param host the host to connect to |
| * @param port the port to connect on |
| * @param context the context to determine access for |
| * |
| * @throws SecurityException if permission is denied, or if context is |
| * not an AccessControlContext |
| * @throws NullPointerException if host is null |
| * |
| * @see #getSecurityContext() |
| * @see AccessControlContext#checkPermission(Permission) |
| */ |
| public void checkConnect(String host, int port, Object context) |
| { |
| if (! (context instanceof AccessControlContext)) |
| throw new SecurityException("Missing context"); |
| AccessControlContext ac = (AccessControlContext) context; |
| if (port == -1) |
| ac.checkPermission(new SocketPermission(host, "resolve")); |
| else |
| // Use the toString() hack to do the null check. |
| ac.checkPermission(new SocketPermission(host.toString() + ":" + port, |
| "connect")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to listen to a specific port for |
| * data. This method is called by ServerSocket.ServerSocket(). The default |
| * implementation checks |
| * <code>SocketPermission("localhost:" + (port == 0 ? "1024-" : "" + port), |
| * "listen")</code>. If you override this, call |
| * <code>super.checkListen</code> rather than throwing an exception. |
| * |
| * @param port the port to listen on |
| * @throws SecurityException if permission is denied |
| * @see ServerSocket#ServerSocket(int) |
| */ |
| public void checkListen(int port) |
| { |
| checkPermission(new SocketPermission("localhost:" |
| + (port == 0 ? "1024-" : "" +port), |
| "listen")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to accept a connection from a |
| * particular host on a particular port. This method is called by |
| * ServerSocket.implAccept(). The default implementation checks |
| * <code>SocketPermission(host + ":" + port, "accept")</code>. If you |
| * override this, call <code>super.checkAccept</code> rather than throwing |
| * an exception. |
| * |
| * @param host the host which wishes to connect |
| * @param port the port the connection will be on |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if host is null |
| * @see ServerSocket#accept() |
| */ |
| public void checkAccept(String host, int port) |
| { |
| // Use the toString() hack to do the null check. |
| checkPermission(new SocketPermission(host.toString() + ":" + port, |
| "accept")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read and write multicast to |
| * a particular address. The default implementation checks |
| * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>. |
| * If you override this, call <code>super.checkMulticast</code> rather than |
| * throwing an exception. |
| * |
| * @param addr the address to multicast to |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if host is null |
| * @since 1.1 |
| */ |
| public void checkMulticast(InetAddress addr) |
| { |
| checkPermission(new SocketPermission(addr.getHostAddress(), |
| "accept,connect")); |
| } |
| |
| /** |
| *Check if the current thread is allowed to read and write multicast to |
| * a particular address with a particular ttl (time-to-live) value. The |
| * default implementation ignores ttl, and checks |
| * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>. |
| * If you override this, call <code>super.checkMulticast</code> rather than |
| * throwing an exception. |
| * |
| * @param addr the address to multicast to |
| * @param ttl value in use for multicast send |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if host is null |
| * @since 1.1 |
| * @deprecated use {@link #checkPermission(Permission)} instead |
| */ |
| public void checkMulticast(InetAddress addr, byte ttl) |
| { |
| checkPermission(new SocketPermission(addr.getHostAddress(), |
| "accept,connect")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read or write all the system |
| * properties at once. This method is called by System.getProperties() |
| * and setProperties(). The default implementation checks |
| * <code>PropertyPermission("*", "read,write")</code>. If you override |
| * this, call <code>super.checkPropertiesAccess</code> rather than |
| * throwing an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see System#getProperties() |
| * @see System#setProperties(Properties) |
| */ |
| public void checkPropertiesAccess() |
| { |
| checkPermission(new PropertyPermission("*", "read,write")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to read a particular system |
| * property (writes are checked directly via checkPermission). This method |
| * is called by System.getProperty() and setProperty(). The default |
| * implementation checks <code>PropertyPermission(key, "read")</code>. If |
| * you override this, call <code>super.checkPropertyAccess</code> rather |
| * than throwing an exception. |
| * |
| * @param key the key of the property to check |
| * |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if key is null |
| * @throws IllegalArgumentException if key is "" |
| * |
| * @see System#getProperty(String) |
| */ |
| public void checkPropertyAccess(String key) |
| { |
| checkPermission(new PropertyPermission(key, "read")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to create a top-level window. If |
| * it is not, the operation should still go through, but some sort of |
| * nonremovable warning should be placed on the window to show that it |
| * is untrusted. This method is called by Window.Window(). The default |
| * implementation checks |
| * <code>AWTPermission("showWindowWithoutWarningBanner")</code>, and returns |
| * true if no exception was thrown. If you override this, use |
| * <code>return super.checkTopLevelWindow</code> rather than returning |
| * false. |
| * |
| * @param window the window to create |
| * @return true if there is permission to show the window without warning |
| * @throws NullPointerException if window is null |
| * @see java.awt.Window#Window(java.awt.Frame) |
| */ |
| public boolean checkTopLevelWindow(Object window) |
| { |
| if (window == null) |
| throw new NullPointerException(); |
| try |
| { |
| checkPermission(new AWTPermission("showWindowWithoutWarningBanner")); |
| return true; |
| } |
| catch (SecurityException e) |
| { |
| return false; |
| } |
| } |
| |
| /** |
| * Check if the current thread is allowed to create a print job. This |
| * method is called by Toolkit.getPrintJob(). The default implementation |
| * checks <code>RuntimePermission("queuePrintJob")</code>. If you override |
| * this, call <code>super.checkPrintJobAccess</code> rather than throwing |
| * an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see java.awt.Toolkit#getPrintJob(java.awt.Frame, String, Properties) |
| * @since 1.1 |
| */ |
| public void checkPrintJobAccess() |
| { |
| checkPermission(new RuntimePermission("queuePrintJob")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to use the system clipboard. This |
| * method is called by Toolkit.getSystemClipboard(). The default |
| * implementation checks <code>AWTPermission("accessClipboard")</code>. If |
| * you override this, call <code>super.checkSystemClipboardAccess</code> |
| * rather than throwing an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see java.awt.Toolkit#getSystemClipboard() |
| * @since 1.1 |
| */ |
| public void checkSystemClipboardAccess() |
| { |
| checkPermission(new AWTPermission("accessClipboard")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to use the AWT event queue. This |
| * method is called by Toolkit.getSystemEventQueue(). The default |
| * implementation checks <code>AWTPermission("accessEventQueue")</code>. |
| * you override this, call <code>super.checkAwtEventQueueAccess</code> |
| * rather than throwing an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see java.awt.Toolkit#getSystemEventQueue() |
| * @since 1.1 |
| */ |
| public void checkAwtEventQueueAccess() |
| { |
| checkPermission(new AWTPermission("accessEventQueue")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to access the specified package |
| * at all. This method is called by ClassLoader.loadClass() in user-created |
| * ClassLoaders. The default implementation gets a list of all restricted |
| * packages, via <code>Security.getProperty("package.access")</code>. Then, |
| * if packageName starts with or equals any restricted package, it checks |
| * <code>RuntimePermission("accessClassInPackage." + packageName)</code>. |
| * If you override this, you should call |
| * <code>super.checkPackageAccess</code> before doing anything else. |
| * |
| * @param packageName the package name to check access to |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if packageName is null |
| * @see ClassLoader#loadClass(String, boolean) |
| * @see Security#getProperty(String) |
| */ |
| public void checkPackageAccess(String packageName) |
| { |
| checkPackageList(packageName, "package.access", "accessClassInPackage."); |
| } |
| |
| /** |
| * Check if the current thread is allowed to define a class into the |
| * specified package. This method is called by ClassLoader.loadClass() in |
| * user-created ClassLoaders. The default implementation gets a list of all |
| * restricted packages, via |
| * <code>Security.getProperty("package.definition")</code>. Then, if |
| * packageName starts with or equals any restricted package, it checks |
| * <code>RuntimePermission("defineClassInPackage." + packageName)</code>. |
| * If you override this, you should call |
| * <code>super.checkPackageDefinition</code> before doing anything else. |
| * |
| * @param packageName the package name to check access to |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if packageName is null |
| * @see ClassLoader#loadClass(String, boolean) |
| * @see Security#getProperty(String) |
| */ |
| public void checkPackageDefinition(String packageName) |
| { |
| checkPackageList(packageName, "package.definition", "defineClassInPackage."); |
| } |
| |
| /** |
| * Check if the current thread is allowed to set the current socket factory. |
| * This method is called by Socket.setSocketImplFactory(), |
| * ServerSocket.setSocketFactory(), and URL.setURLStreamHandlerFactory(). |
| * The default implementation checks |
| * <code>RuntimePermission("setFactory")</code>. If you override this, call |
| * <code>super.checkSetFactory</code> rather than throwing an exception. |
| * |
| * @throws SecurityException if permission is denied |
| * @see Socket#setSocketImplFactory(SocketImplFactory) |
| * @see ServerSocket#setSocketFactory(SocketImplFactory) |
| * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory) |
| */ |
| public void checkSetFactory() |
| { |
| checkPermission(new RuntimePermission("setFactory")); |
| } |
| |
| /** |
| * Check if the current thread is allowed to get certain types of Methods, |
| * Fields and Constructors from a Class object. This method is called by |
| * Class.getMethod[s](), Class.getField[s](), Class.getConstructor[s], |
| * Class.getDeclaredMethod[s](), Class.getDeclaredField[s](), and |
| * Class.getDeclaredConstructor[s](). The default implementation allows |
| * PUBLIC access, and access to classes defined by the same classloader as |
| * the code performing the reflection. Otherwise, it checks |
| * <code>RuntimePermission("accessDeclaredMembers")</code>. If you override |
| * this, do not call <code>super.checkMemberAccess</code>, as this would |
| * mess up the stack depth check that determines the ClassLoader requesting |
| * the access. |
| * |
| * @param c the Class to check |
| * @param memberType either DECLARED or PUBLIC |
| * @throws SecurityException if permission is denied, including when |
| * memberType is not DECLARED or PUBLIC |
| * @throws NullPointerException if c is null |
| * @see Class |
| * @see Member#DECLARED |
| * @see Member#PUBLIC |
| * @since 1.1 |
| */ |
| public void checkMemberAccess(Class c, int memberType) |
| { |
| if (c == null) |
| throw new NullPointerException(); |
| if (memberType == Member.PUBLIC) |
| return; |
| // XXX Allow access to classes created by same classloader before next |
| // check. |
| checkPermission(new RuntimePermission("accessDeclaredMembers")); |
| } |
| |
| /** |
| * Test whether a particular security action may be taken. The default |
| * implementation checks <code>SecurityPermission(action)</code>. If you |
| * override this, call <code>super.checkSecurityAccess</code> rather than |
| * throwing an exception. |
| * |
| * @param action the desired action to take |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if action is null |
| * @throws IllegalArgumentException if action is "" |
| * @since 1.1 |
| */ |
| public void checkSecurityAccess(String action) |
| { |
| checkPermission(new SecurityPermission(action)); |
| } |
| |
| /** |
| * Get the ThreadGroup that a new Thread should belong to by default. Called |
| * by Thread.Thread(). The default implementation returns the current |
| * ThreadGroup of the current Thread. <STRONG>Spec Note:</STRONG> it is not |
| * clear whether the new Thread is guaranteed to pass the |
| * checkAccessThreadGroup() test when using this ThreadGroup, but I presume |
| * so. |
| * |
| * @return the ThreadGroup to put the new Thread into |
| * @since 1.1 |
| */ |
| public ThreadGroup getThreadGroup() |
| { |
| return Thread.currentThread().getThreadGroup(); |
| } |
| |
| /** |
| * Helper that checks a comma-separated list of restricted packages, from |
| * <code>Security.getProperty("package.definition")</code>, for the given |
| * package access permission. If packageName starts with or equals any |
| * restricted package, it checks |
| * <code>RuntimePermission(permission + packageName)</code>. |
| * |
| * @param packageName the package name to check access to |
| * @param restriction "package.access" or "package.definition" |
| * @param permission the base permission, including the '.' |
| * @throws SecurityException if permission is denied |
| * @throws NullPointerException if packageName is null |
| * @see #checkPackageAccess(String) |
| * @see #checkPackageDefinition(String) |
| */ |
| void checkPackageList(String packageName, final String restriction, |
| String permission) |
| { |
| if (packageName == null) |
| throw new NullPointerException(); |
| |
| String list = (String)AccessController.doPrivileged(new PrivilegedAction() |
| { |
| public Object run() |
| { |
| return Security.getProperty(restriction); |
| } |
| }); |
| |
| if (list == null || list.equals("")) |
| return; |
| |
| String packageNamePlusDot = packageName + "."; |
| |
| StringTokenizer st = new StringTokenizer(list, ","); |
| while (st.hasMoreTokens()) |
| { |
| if (packageNamePlusDot.startsWith(st.nextToken())) |
| { |
| Permission p = new RuntimePermission(permission + packageName); |
| checkPermission(p); |
| return; |
| } |
| } |
| } |
| } |