University of Virginia, Department of Computer Science
CS551: Security and Privacy on the Internet, Fall 2000

SecurityManager

/*
 * @(#)SecurityManager.java	1.48 97/03/10
 * 
 * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of Sun
 * Microsystems, Inc. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Sun.
 * 
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 * 
 * CopyrightVersion 1.1_beta
 * 
 */

package java.lang;

import java.io.FileDescriptor;
import java.util.Hashtable;
import java.net.InetAddress;
import java.lang.reflect.Member;

/**
 * The security manager is an abstract class that allows 
 * applications to implement a security policy. It allows an 
 * application to determine, before performing a possibly unsafe or 
 * sensitive operation, what the operation is and whether the 
 * operation is being performed by a class created via a class loader 
 * rather than installed locally. Classes loaded via a class loader 
 * (especially if they have been downloaded over a network) may be 
 * less trustworthy than classes from files installed locally. The 
 * application can allow or disallow the operation. 
 * 

* The SecurityManager class contains many methods with * names that begin with the word check. These methods * are called by various methods in the Java libraries before those * methods perform certain potentially sensitive operations. The * invocation of such a check method typically looks like this: *

 *     SecurityManager security = System.getSecurityManager();
 *     if (security != null) {
 *         security.checkXXX(argument,  . . . );
 *     }
 * 
*

* The security manager is thereby given an opportunity to prevent * completion of the operation by throwing an exception. A security * manager routine simply returns if the operation is permitted, but * throws a SecurityException if the operation is not * permitted. The only exception to this convention is * checkTopLevelWindow, which returns a * boolean value. *

* The current security manager is set by the * setSecurityManager method in class * System. The current security manager is obtained * by the getSecurityManager method. *

* The default implementation of each of the * checkXXX methods is to assume that the caller * does not have permission to perform the requested operation. * * @author Arthur van Hoff * @version 1.48, 03/10/97 * @see java.lang.ClassLoader * @see java.lang.SecurityException * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) * @see java.lang.System#getSecurityManager() * @see java.lang.System#setSecurityManager(java.lang.SecurityManager) * @since JDK1.0 */ public abstract class SecurityManager { /** * This field is true if there is a security check in * progress; false otherwise. * * @since JDK1.0 */ protected boolean inCheck; /* * Have we been initialized. Effective against finalizer attacks. */ private boolean initialized = false; /** * Tests if there is a security check in progress. * * @return the value of the inCheck field. This field should * contain true if a security check is in progress; * false otherwise. * @see java.lang.SecurityManager#inCheck * @since JDK1.0 */ public boolean getInCheck() { return inCheck; } /** * Constructs a new SecurityManager. An application is * not allowed to create a new security manager if there is already a * current security manager. * * @exception SecurityException if a security manager already exists. * @see java.lang.System#getSecurityManager() * @since JDK1.0 */ protected SecurityManager() { if (System.getSecurityManager() != null) { throw new SecurityException("security manager already installed."); } initialized = true; } /** * Returns the current execution stack as an array of classes. *

* The length of the array is the number of methods on the execution * stack. The element at index 0 is the class of the * currently executing method, the element at index 1 is * the class of that method's caller, and so on. * * @return the execution stack. * @since JDK1.0 */ protected native Class[] getClassContext(); /** * Returns an object describing the most recent class loader executing * on the stack. * * @return the class loader of the most recent occurrence on the stack * of a method from a class defined using a class loader; * returns null if there is no occurrence on the * stack of a method from a class defined using a class loader. * @since JDK1.0 */ protected native ClassLoader currentClassLoader(); /** * Returns the current Class with a ClassLoader on the execution stack. * * @since JDK1.1 */ protected Class currentLoadedClass() { return currentLoadedClass0(); } /** * Returns the stack depth of the specified class. * * @param name the fully qualified name of the class to search for. * @return the depth on the stack frame of the first occurrence of a * method from a class with the specified name; * -1 if such a frame cannot be found. * @since JDK1.0 */ protected native int classDepth(String name); /** * Returns the stack depth of the most recently executing method * from a class defined using a class loader. * * @return the depth on the stack frame of the most recent occurrence of a * method from a class defined using a class loader; returns * -1 if there is no occurrence of a method from * a class defined using a class loader. * @since JDK1.0 */ protected native int classLoaderDepth(); /** * Tests if the specified String is in this Class. * * @param name the fully qualified name of the class. * @return true if a method from a class with the specified * name is on the execution stack; false otherwise. * @since JDK1.0 */ protected boolean inClass(String name) { return classDepth(name) >= 0; } /** * Tests if the current ClassLoader is equal to * null. * * @return true if a method from a class defined using a * class loader is on the execution stack. * @since JDK1.0 */ protected boolean inClassLoader() { return currentClassLoader() != null; } /** * Creates an object that encapsulates the current execution * environment. The result of this method is used by the * three-argument checkConnect method and by the * two-argument checkRead method. *

* These methods are needed because a trusted method may be called * on to read a file or open a socket on behalf of another method. * The trusted method needs to determine if the other (possibly * untrusted) method would be allowed to perform the operation on its * own. * * @return an implementation-dependent object that encapsulates * sufficient information about the current execution environment * to perform some security checks later. * @see java.lang.SecurityManager#checkConnect(java.lang.String, int, java.lang.Object) * @see java.lang.SecurityManager#checkRead(java.lang.String, java.lang.Object) * @since JDK1.0 */ public Object getSecurityContext() { return null; } /** * Throws a SecurityException if the * calling thread is not allowed to create a new class loader. *

* The checkCreateClassLoader method for class * SecurityManager always throws a * SecurityException. * * @exception SecurityException if the caller does not have permission * to create a new class loader. * @see java.lang.ClassLoader#ClassLoader() * @since JDK1.0 */ public void checkCreateClassLoader() { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to modify the thread argument. *

* This method is invoked for the current security manager by the * stop, suspend, resume, * setPriority, setName, and * setDaemon methods of class Thread. *

* The checkAccess method for class * SecurityManager always throws a * SecurityException. * * @param g the thread to be checked. * @exception SecurityException if the caller does not have permission * to modify the thread. * @see java.lang.System#getSecurityManager() * @see java.lang.Thread#resume() * @see java.lang.Thread#setDaemon(boolean) * @see java.lang.Thread#setName(java.lang.String) * @see java.lang.Thread#setPriority(int) * @see java.lang.Thread#stop() * @see java.lang.Thread#suspend() * @since JDK1.0 */ public void checkAccess(Thread g) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to modify the thread group argument. *

* This method is invoked for the current security manager when a * new child thread or child thread group is created, and by the * setDaemon, setMaxPriority, * stop, suspend, resume, and * destroy methods of class ThreadGroup. *

* The checkAccess method for class * SecurityManager always throws a * SecurityException. * * @param g the thread group to be checked. * @exception SecurityException if the caller does not have permission * to modify the thread group. * @see java.lang.System#getSecurityManager() * @see java.lang.ThreadGroup#destroy() * @see java.lang.ThreadGroup#resume() * @see java.lang.ThreadGroup#setDaemon(boolean) * @see java.lang.ThreadGroup#setMaxPriority(int) * @see java.lang.ThreadGroup#stop() * @see java.lang.ThreadGroup#suspend() * @since JDK1.0 */ public void checkAccess(ThreadGroup g) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to cause the Java Virtual Machine to * halt with the specified status code. *

* This method is invoked for the current security manager by the * exit method of class Runtime. A status * of 0 indicates success; other values indicate various * errors. *

* The checkExit method for class * SecurityManager always throws a * SecurityException. * * @param status the exit status. * @exception SecurityException if the caller does not have permission * to halt the Java Virtual Machine with the specified status. * @see java.lang.Runtime#exit(int) * @see java.lang.System#getSecurityManager() * @since JDK1.0 */ public void checkExit(int status) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to create a subprocss. *

* This method is invoked for the current security manager by the * exec methods of class Runtime. *

* The checkExec method for class * SecurityManager always throws a * SecurityException. * * @param cmd the specified system command. * @exception SecurityException if the caller does not have permission * to create a subprocess. * @see java.lang.Runtime#exec(java.lang.String) * @see java.lang.Runtime#exec(java.lang.String, java.lang.String[]) * @see java.lang.Runtime#exec(java.lang.String[]) * @see java.lang.Runtime#exec(java.lang.String[], java.lang.String[]) * @see java.lang.System#getSecurityManager() * @since JDK1.0 */ public void checkExec(String cmd) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to dynamic link the library code * specified by the string argument file. The argument is either a * simple library name or a complete filename. *

* This method is invoked for the current security manager by * methods load and loadLibrary of class * Runtime. *

* The checkLink method for class * SecurityManager always throws a * SecurityException. * * @param lib the name of the library. * @exception SecurityException if the caller does not have permission * to dynamically link the library. * @see java.lang.Runtime#load(java.lang.String) * @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.System#getSecurityManager() * @since JDK1.0 */ public void checkLink(String lib) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to read from the specified file * descriptor. *

* The checkRead method for class * SecurityManager always throws a * SecurityException. * * @param fd the system-dependent file descriptor. * @exception SecurityException if the caller does not have permission * to access the specified file descriptor. * @see java.io.FileDescriptor * @since JDK1.0 */ public void checkRead(FileDescriptor fd) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to read the file specified by the * string argument. *

* The checkRead method for class * SecurityManager always throws a * SecurityException. * * @param file the system-dependent file name. * @exception SecurityException if the caller does not have permission * to access the specified file. * @since JDK1.0 */ public void checkRead(String file) { throw new SecurityException(); } /** * Throws a SecurityException if the * specified security context is not allowed to read the file * specified by the string argument. The context must be a security * context returned by a previous call to * getSecurityContext. *

* The checkRead method for class * SecurityManager always throws a * SecurityException. * * @param file the system-dependent filename. * @param context a system-dependent security context. * @exception SecurityException if the specified security context does * not have permission to read the specified file. * @see java.lang.SecurityManager#getSecurityContext() * @since JDK1.0 */ public void checkRead(String file, Object context) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to write to the specified file * descriptor. *

* The checkWrite method for class * SecurityManager always throws a * SecurityException. * * @param fd the system-dependent file descriptor. * @exception SecurityException if the caller does not have permission * to access the specified file descriptor. * @see java.io.FileDescriptor * @since JDK1.0 */ public void checkWrite(FileDescriptor fd) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to write to the file specified by * the string argument. *

* The checkWrite method for class * SecurityManager always throws a * SecurityException. * * @param file the system-dependent filename. * @exception SecurityException if the caller does not have permission * to access the specified file. * @since JDK1.0 */ public void checkWrite(String file) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to delete the specified file. *

* This method is invoked for the current security manager by the * delete method of class File. *

* The checkDelete method for class * SecurityManager always throws a * SecurityException. * * @param file the system-dependent filename. * @exception SecurityException if the caller does not have permission * to delete the file. * @see java.io.File#delete() * @see java.lang.System#getSecurityManager() * @since JDK1.0 */ public void checkDelete(String file) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to open a socket connection to the * specified host and port number. *

* A port number of -1 indicates that the calling * method is attempting to determine the IP address of the specified * host name. *

* The checkConnect method for class * SecurityManager always throws a * SecurityException. * * @param host the host name port to connect to. * @param port the protocol port to connect to. * @exception SecurityException if the caller does not have permission * to open a socket connection to the specified * host and port. * @since JDK1.0 */ public void checkConnect(String host, int port) { throw new SecurityException(); } /** * Throws a SecurityException if the * specified security context is not allowed to open a socket * connection to the specified host and port number. *

* A port number of -1 indicates that the calling * method is attempting to determine the IP address of the specified * host name. *

* The checkConnect method for class * SecurityManager always throws a * SecurityException. * * @param host the host name port to connect to. * @param port the protocol port to connect to. * @param context a system-dependent security context. * @exception SecurityException if the specified security context does * not have permission to open a socket connection to the * specified host and port. * @see java.lang.SecurityManager#getSecurityContext() * @since JDK1.0 */ public void checkConnect(String host, int port, Object context) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to wait for a connection request on * the specified local port number. *

* The checkListen method for class * SecurityManager always throws a * SecurityException. * * @param port the local port. * @exception SecurityException if the caller does not have permission * to listen on the specified port. * @since JDK1.0 */ public void checkListen(int port) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not permitted to accept a socket connection from * the specified host and port number. *

* This method is invoked for the current security manager by the * accept method of class ServerSocket. *

* The checkAccept method for class * SecurityManager always throws a * SecurityException. * * @param host the host name of the socket connection. * @param port the port number of the socket connection. * @exception SecurityException if the caller does not have permission * to accept the connection. * @see java.lang.System#getSecurityManager() * @see java.net.ServerSocket#accept() * @since JDK1.0 */ public void checkAccept(String host, int port) { throw new SecurityException(); } /** * Tests if current execution context is allowed to use * (join/leave/send/receive) IP multicast. * * @param multicast Internet group address to be used. * @exception SecurityException if a security error has occurred. * @since JDK1.1 */ public void checkMulticast(InetAddress maddr) { throw new SecurityException(); } /** * Tests to see if current execution context is allowed to use * (join/leave/send/receive) IP multicast. * * @param multicast Internet group address to be used. * @param ttl value in use, if it is multicast send. * @exception SecurityException if a security error has occurred. * @since JDK1.1 */ public void checkMulticast(InetAddress maddr, byte ttl) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to access or modify the system * properties. *

* This method is used by the getProperties and * setProperties methods of class System. *

* The checkPropertiesAccess method for class * SecurityManager always throws a * SecurityException. * * @exception SecurityException if the caller does not have permission * to access or modify the system properties. * @see java.lang.System#getProperties() * @see java.lang.System#setProperties(java.util.Properties) * @since JDK1.0 */ public void checkPropertiesAccess() { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to access the system property with * the specified key name. *

* This method is used by the getProperty method of * class System. *

* The checkPropertiesAccess method for class * SecurityManager always throws a * SecurityException. * * @param key a system property key. * @exception SecurityException if the caller does not have permission * to access the specified system property. * @see java.lang.System#getProperty(java.lang.String) * @since JDK1.0 */ public void checkPropertyAccess(String key) { throw new SecurityException(); } /** * Returns false if the calling * thread is not trusted to bring up the top-level window indicated * by the window argument. In this case, the caller can * still decide to show the window, but the window should include * some sort of visual warning. If the method returns * true, then the window can be shown without any * special restrictions. *

* See class Window for more information on trusted and * untrusted windows. *

* The checkSetFactory method for class * SecurityManager always returns false. * * @param window the new window that is being created. * @return true if the caller is trusted to put up * top-level windows; false otherwise. * @exception SecurityException if creation is disallowed entirely. * @see java.awt.Window * @since JDK1.0 */ public boolean checkTopLevelWindow(Object window) { return false; } /** * Tests if a client can initiate a print job request. * * @since JDK1.1 */ public void checkPrintJobAccess() { throw new SecurityException(); } /** * Tests if a client can get access to the system clipboard. * * @since JDK1.1 */ public void checkSystemClipboardAccess() { throw new SecurityException(); } /** * Tests if a client can get access to the AWT event queue. * * @since JDK1.1 */ public void checkAwtEventQueueAccess() { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to access the package specified by * the argument. *

* This method is used by the loadClass method of class * loaders. *

* The checkPackageAccess method for class * SecurityManager always throws a * SecurityException. * * @param pkg the package name. * @exception SecurityException if the caller does not have permission * to access the specified package. * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) * @since JDK1.0 */ public void checkPackageAccess(String pkg) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to define classes in the package * specified by the argument. *

* This method is used by the loadClass method of some * class loaders. *

* The checkPackageDefinition method for class * SecurityManager always throws a * SecurityException. * * @param pkg the package name. * @exception SecurityException if the caller does not have permission * to define classes in the specified package. * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) * @since JDK1.0 */ public void checkPackageDefinition(String pkg) { throw new SecurityException(); } /** * Throws a SecurityException if the * calling thread is not allowed to set the socket factory used by * ServerSocket or Socket, or the stream * handler factory used by URL. *

* The checkSetFactory method for class * SecurityManager always throws a * SecurityException. * * @exception SecurityException if the caller does not have permission * to specify a socket factory or a stream handler factory. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.URL#setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory) * @since JDK1.0 */ public void checkSetFactory() { throw new SecurityException(); } /** * Tests if a client is allowed to access members. If access is * denied, throw a SecurityException. * The default policy is to deny all accesses. * * @since JDK1.1 */ public void checkMemberAccess(Class clazz, int which) { throw new SecurityException(); } /** * Tests access to certain operations for a security API * action. * * @since JDK1.1 */ public void checkSecurityAccess(String action) { throw new SecurityException(); } private native Class currentLoadedClass0(); /** * Returns the thread group into which to instantiate any new * thread being created at the time this is being called. * By default, it returns the thread group of the current * thread. This should be overriden by specific security * manager to return the appropriate thread group. * * @since JDK1.1 */ public ThreadGroup getThreadGroup() { return Thread.currentThread().getThreadGroup(); } } class NullSecurityManager extends SecurityManager { public void checkCreateClassLoader() { } public void checkAccess(Thread g) { } public void checkAccess(ThreadGroup g) { } public void checkExit(int status) { } public void checkExec(String cmd) { } public void checkLink(String lib) { } public void checkRead(FileDescriptor fd) { } public void checkRead(String file) { } public void checkRead(String file, Object context) { } public void checkWrite(FileDescriptor fd) { } public void checkWrite(String file) { } public void checkDelete(String file) { } public void checkConnect(String host, int port) { } public void checkConnect(String host, int port, Object context) { } public void checkListen(int port) { } public void checkAccept(String host, int port) { } public void checkMulticast(InetAddress maddr) { } public void checkMulticast(InetAddress maddr, byte ttl) { } public void checkPropertiesAccess() { } public void checkPropertyAccess(String key) { } public void checkPropertyAccess(String key, String def) { } public boolean checkTopLevelWindow(Object window) { return true; } public void checkPrintJobAccess() { } public void checkSystemClipboardAccess() { } public void checkAwtEventQueueAccess() { } public void checkPackageAccess(String pkg) { } public void checkPackageDefinition(String pkg) { } public void checkSetFactory() { } public void checkMemberAccess(Class clazz, int which) { } public void checkSecurityAccess(String provider) { } }


CS 655 University of Virginia
Department of Computer Science
CS 551: Security and Privacy on the Internet
David Evans
evans@cs.virginia.edu