summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2002-03-06 19:44:44 +0000
committerEric Blake <ebb9@byu.net>2002-03-06 19:44:44 +0000
commit17c3f9b21a1503325cafd893332decf6c003a916 (patch)
treeb76fe7e6ed37726c5687bb3d2eacd444561c61e5 /java
parente2c44b08d79dbbbb6ddd4d1544a90d4d1cc5f8d2 (diff)
downloadclasspath-17c3f9b21a1503325cafd893332decf6c003a916.tar.gz
2002-03-06 Eric Blake <ebb9@email.byu.edu>
* java/lang/RuntimePermission.java: Improve Javadoc. * java/lang/SecurityManager.java: Improve Javadoc and formatting. * java/lang/System.java (setIn, setOut, setErr): Add required security check. (defaultProperties): Add a default, to allow clean resetting of properties back to the VM startup state. (setProperties): Correctly reset properties to default state. * native/jni/java-lang/java_lang_System.c: Update method signatures for changing I/O. * include/java_lang_System.h: Ditto. * vm/reference/java/lang/Runtime.java: Add shutdown hook capability, as well as updating the exec calls. * vm/reference/java/lang/VMSecurityManager.java: Improve Javadoc. * java/util/PropertyPermission.java: Fix implication bugs. * java/util/PropertyPermissionCollection.java: Ditto.
Diffstat (limited to 'java')
-rw-r--r--java/lang/RuntimePermission.java156
-rw-r--r--java/lang/SecurityManager.java1703
-rw-r--r--java/lang/System.java332
-rw-r--r--java/util/PropertyPermission.java24
-rw-r--r--java/util/PropertyPermissionCollection.java25
5 files changed, 1305 insertions, 935 deletions
diff --git a/java/lang/RuntimePermission.java b/java/lang/RuntimePermission.java
index 81bc44c1e..0b5b5f878 100644
--- a/java/lang/RuntimePermission.java
+++ b/java/lang/RuntimePermission.java
@@ -1,5 +1,5 @@
-/* RuntimePermission.java
- Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+/* RuntimePermission.java -- permission for a secure runtime action
+ Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ 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
@@ -38,14 +38,14 @@ exception statement from your version. */
package java.lang;
-import java.security.*;
+import java.security.BasicPermission;
/**
* A <code>RuntimePermission</code> contains a permission name, but no
* actions list. This means you either have the permission or you don't.
*
* Permission names have the follow the hierarchial property naming
- * convention. In addition, an asterisk may appear at the end of a
+ * convention. In addition, an asterisk may appear at the end of a
* name if following a period or by itself.
*
* <table border=1>
@@ -53,112 +53,156 @@ import java.security.*;
* <tr><td>"accessClassInPackage.*","*"</td>
* <td>"**", "*x", "*.a"</td></tr>
* </table>
- * <br>
- *
- * The following table provides a list of all the possible RuntimePermission
- * permission names with a description of what that permission allows.
* <br>
+ *
+ * The following table provides a list of all the possible RuntimePermission
+ * permission names with a description of what that permission allows.<br>
* <table border=1>
- * <tr><th>Permission Name</th><th>Permission Allows</th></tr>
+ * <tr><th>Permission Name</th><th>Permission Allows</th><th>Risks</th</tr>
* <tr>
* <td><code>createClassLoader</code></td>
- * <td>creation of a class loader</td></tr>
+ * <td>creation of a class loader</td>
+ * <td>a class loader can load rogue classes which bypass all security
+ * permissions</td></tr>
* <tr>
* <td><code>getClassLoader</code></td>
- * <td>retrieval of the class loader for the calling class</td></tr>
+ * <td>retrieval of the class loader for the calling class</td>
+ * <td>rogue code could load classes not otherwise available</td></tr>
* <tr>
* <td><code>setContextClassLoader</code></td>
- * <td>allows the setting of the context class loader used by a
- * thread including system threads</td></tr>
+ * <td>allows the setting of the context class loader used by a thread</td>
+ * <td>rogue code could change the context class loader needed by system
+ * threads</td></tr>
* <tr>
* <td><code>setSecurityManager</code></td>
- * <td>allows the application to replace the security manager with
- * another, possibly less restrictive one.</td></tr>
+ * <td>allows the application to replace the security manager</td>
+ * <td>the new manager may be less restrictive, so that rogue code can
+ * bypass existing security checks</td></tr>
* <tr>
* <td><code>createSecurityManager</code></td>
- * <td>allows the application to create a new security manager</td></tr>
+ * <td>allows the application to create a new security manager</td>
+ * <td>rogue code can use the new security manager to discover information
+ * about the execution stack</td></tr>
* <tr>
* <td><code>exitVM</code></td>
- * <td>allows the application to halt the virtual machine</td></tr>
+ * <td>allows the application to halt the virtual machine</td>
+ * <td>rogue code can mount a denial-of-service attack by killing the
+ * virtual machine</td></tr>
+ * <tr>
+ * <td><code>shutdownHooks</code></td>
+ * <td>allows registration and modification of shutdown hooks</td>
+ * <td>rogue code can add a hook that interferes with clean
+ * virtual machine shutdown</td></tr>
* <tr>
* <td><code>setFactory</code></td>
- * <td>allows the application to set the socket factory for socket,
- * server socket, stream handler, or RMI socket factory.</td></tr>
+ * <td>allows the application to set the socket factory for socket,
+ * server socket, stream handler, or RMI socket factory.</td>
+ * <td>rogue code can create a rogue network object which mangles or
+ * intercepts data</td></tr>
* <tr>
* <td><code>setIO</code></td>
- * <td>allows the application to set System.out, System.in, and
- * System.err</td></tr>
+ * <td>allows the application to set System.out, System.in, and
+ * System.err</td>
+ * <td>rogue code could sniff user input and intercept or mangle
+ * output</td></tr>
* <tr>
* <td><code>modifyThread</code></td>
* <td>allows the application to modify any thread in the virtual machine
* using any of the methods <code>stop</code>, <code>resume</code>,
- * <code>suspend</code>, <code>setPriority</code>, and
- * <code>setName</code> of classs <code>Thread</code></td></tr>
+ * <code>suspend</code>, <code>setPriority</code>, and
+ * <code>setName</code> of classs <code>Thread</code></td>
+ * <td>rogue code could adversely modify system or user threads</td></tr>
* <tr>
* <td><code>stopThread</code></td>
* <td>allows the application to <code>stop</code> any thread it has
- * access to in the system</td></tr>
+ * access to in the system</td>
+ * <td>rogue code can stop arbitrary threads</td></tr>
* <tr>
* <td><code>modifyThreadGroup</td>
* <td>allows the application to modify thread groups using any of the
- * methods <code>destroy</code>, <code>resume</code>,
- * <code>setDaemon</code>, <code>setMaxPriority</code>,
+ * methods <code>destroy</code>, <code>resume</code>,
+ * <code>setDaemon</code>, <code>setMaxPriority</code>,
* <code>stop</code>, and <code>suspend</code> of the class
- * <code>ThreadGroup</code></td></tr>
+ * <code>ThreadGroup</code></td>
+ * <td>rogue code can mount a denial-of-service attack by changing run
+ * priorities</td></tr>
* <tr>
* <td><code>getProtectionDomain</code></td>
- * <td></td></tr>
+ * <td>retrieve a class's ProtectionDomain</td>
+ * <td>rogue code can gain information about the security policy, to
+ * prepare a better attack</td></tr>
* <tr>
* <td><code>readFileDescriptor</code></td>
- * <td></td></tr>
+ * <td>read a file descriptor</td>
+ * <td>rogue code can read sensitive information</td></tr>
* <tr>
- * <td><code>writeFileDescriptor</code</td>
- * <td></td></tr>
+ * <td><code>writeFileDescriptor</code></td>
+ * <td>write a file descriptor</td>
+ * <td>rogue code can write files, including viruses, and can modify the
+ * virtual machine binary; if not just fill up the disk</td></tr>
* <tr>
- * <td><code>loadLibrary.{library name}</code></td>
- * <td></td></tr>
+ * <td><code>loadLibrary.<code><em>library name</em></td>
+ * <td>dynamic linking of the named library</td>
+ * <td>native code can bypass many security checks of pure Java</td></tr>
* <tr>
- * <td><code>accessClassInPackage.{package name}</code></td>
- * <td></td></tr>
+ * <td><code>accessClassInPackage.</code><em>package name</em></td>
+ * <td>access to a package via a ClassLoader</td>
+ * <td>rogue code can access classes not normally available</td></tr>
* <tr>
- * <td><code>defineClassInPackage.{package name}</code></td>
- * <td></td></tr>
+ * <td><code>defineClassInPackage.</code><em>package name</em></td>
+ * <td>define a class inside a given package</td>
+ * <td>rogue code can install rogue classes, including in trusted packages
+ * like java.security or java.lang</td></tr>
* <tr>
* <td><code>accessDeclaredMembers</code></td>
- * <td></td></tr>
+ * <td>access declared class members via reflection</td>
+ * <td>rogue code can discover information, invoke methods, or modify fields
+ * that are not otherwise available</td></tr>
* <tr>
* <td><code>queuePrintJob</code></td>
- * <td></td></tr>
+ * <td>initiate a print job</td>
+ * <td>rogue code could make a hard copy of sensitive information, or
+ * simply waste paper</td></tr>
* </table>
- *
- * @since JDK 1.2
- *
+ *
* @author Brian Jones
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see BasicPermission
+ * @see Permission
+ * @see SecurityManager
+ * @since 1.2
+ * @status updated to 1.4
*/
-public final class RuntimePermission extends java.security.BasicPermission
+public final class RuntimePermission extends BasicPermission
{
/**
- *
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 7399184964622342223L;
+
+ /**
+ * Create a new permission with the specified name.
+ *
* @param permissionName the name of the granted permission
- *
- * @throws IllegalArgumentException thrown if the name contains an invalid
- * wildcard character
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException thrown if name is empty or invalid
*/
public RuntimePermission(String permissionName)
{
- this(permissionName, null);
+ super(permissionName);
}
/**
+ * Create a new permission with the specified name. The actions argument
+ * is ignored, as runtime permissions have no actions.
*
* @param permissionName the name of the granted permission
- * @param actions this should always be null
- *
- * @throws IllegalArgumentException throw if the name contains an invalid
- * wildcard character
+ * @param actions ignored
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException thrown if name is empty or invalid
*/
public RuntimePermission(String permissionName, String actions)
- {
- super(permissionName, actions);
- }
+ {
+ super(permissionName);
+ }
}
diff --git a/java/lang/SecurityManager.java b/java/lang/SecurityManager.java
index 3ae049c40..1f73fdd3d 100644
--- a/java/lang/SecurityManager.java
+++ b/java/lang/SecurityManager.java
@@ -1,5 +1,5 @@
-/* java.lang.SecurityManager
- Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+/* SecurityManager.java -- security checks for privileged actions
+ Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ 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
@@ -38,736 +38,977 @@ exception statement from your version. */
package java.lang;
-import java.net.*;
-import java.util.*;
-import java.io.*;
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.security.Permission;
+import java.security.SecurityPermission;
/**
- ** 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.<P>
- **
- ** The default methods in this class deny all
- ** things to all people.
- **
- ** @author John Keiser
- ** @version 1.1.0, 31 May 1998
- ** @since JDK1.0
- **/
-public class SecurityManager {
- /** Tells whether or not the SecurityManager is currently
- ** performing a security check.
- **/
- protected boolean inCheck;
-
- /** Tells whether or not the SecurityManager is currently
- ** performing a security check.
- **
- ** @return whether or not the SecurityManager is
- ** currently performing a security check.
- **/
- 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
- ** <STRONG>Spec Note:</STRONG> does not say whether
- ** the stack will include the getClassContext() call or
- ** the one just before it.
- **
- ** @return an array containing all the methods on classes
- ** on the Java execution stack.
- **/
- protected Class[] getClassContext() {
- return VMSecurityManager.getClassContext();
- }
-
- /** Find the ClassLoader for the most recent class on the
- ** stack that was loaded by an explicit ClassLoader. If
- ** everything on the stack was loaded by the system
- ** classloader, null is returned.
- **
- ** @return the most recent ClassLoader on the execution
- ** stack.
- **/
- protected ClassLoader currentClassLoader() {
- return VMSecurityManager.currentClassLoader();
- }
-
- /** Find the most recent class on the stack that was
- ** loaded by an explicit ClassLoader. If everything on
- ** the stack was loaded by the system classloader, null
- ** is returned.
- **
- ** @return the most recent loaded Class on the execution
- ** stack.
- **/
- protected Class currentLoadedClass() {
- Class[] c = getClassContext();
- for(int i=0;i<c.length;i++) {
- if(c[i].getClassLoader() != null) {
- return c[i];
- }
- }
- return null;
- }
-
- /** Get the depth on the execution stack of the most
- ** recent class that was loaded by an explicit
- ** ClassLoader. This can be used as an index into
- ** getClassContext().
- **
- ** @return the index of the most recent loaded Class on
- ** the execution stack.
- **/
- protected int classLoaderDepth() {
- Class[] c = getClassContext();
- for(int i=0;i<c.length;i++) {
- if(c[i].getClassLoader() != null) {
- return i;
- }
- }
- return -1;
- }
-
- /** Tell whether there is a class loaded with an explicit
- ** ClassLoader on the stack.
- **
- ** @return whether there is a class loaded with an
- ** explicit ClassLoader on the stack.
- **/
- protected boolean inClassLoader() {
- return classLoaderDepth() != -1;
- }
-
-
- /** Get the depth of a particular class on the execution
- ** stack.
- **
- ** @param className the fully-qualified name of the class
- ** to search for on the stack.
- ** @return the index of the class on the stack, or -1 if
- ** the class is not on the stack.
- **/
- 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;
- }
-
- /** Tell whether the specified class is on the execution
- ** stack.
- **
- ** @param className the fully-qualified name of the class
- ** to search for on the stack.
- ** @return whether the specified class is on the
- ** execution stack.
- **/
- protected boolean inClass(String className) {
- return classDepth(className) != -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().
- **
- ** @see checkConnect(java.lang.String,int,java.lang.Object)
- ** @see checkRead(java.lang.String,java.lang.Object)
- **/
- public Object getSecurityContext() {
- return new SecurityContext(getClassContext());
- }
-
- /** Check if the current thread is allowed to create a
- ** ClassLoader.<P>
- **
- ** This method is called from ClassLoader.ClassLoader(),
- ** in other words, whenever a ClassLoader is created.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.ClassLoader#ClassLoader()
- **/
- public void checkCreateClassLoader() {
- throw new SecurityException("Cannot create new ClassLoaders.");
- }
-
- /** Check if the current thread is allowed to modify this
- ** other Thread.<P>
- **
- ** Called by Thread.stop(), suspend(), resume(), and
- ** interrupt(), destroy(), setPriority(), setName() and
- ** setDaemon().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param g the Thread to check against
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Thread#stop()
- ** @see java.lang.Thread#suspend()
- ** @see java.lang.Thread#resume()
- ** @see java.lang.Thread#interrupt()
- ** @see java.lang.Thread#destroy()
- ** @see java.lang.Thread#setPriority(int)
- ** @see java.lang.Thread#setName(java.lang.String)
- ** @see java.lang.Thread#setDaemon(boolean)
- **/
- public void checkAccess(Thread t) {
- throw new SecurityException("Cannot modify Threads.");
- }
-
- /** Check if the current thread is allowed to modify this
- ** ThreadGroup.<P>
- **
- ** 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().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param g the ThreadGroup to check against
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Thread#Thread()
- ** @see java.lang.ThreadGroup#ThreadGroup()
- ** @see java.lang.ThreadGroup#stop()
- ** @see java.lang.ThreadGroup#suspend()
- ** @see java.lang.ThreadGroup#resume()
- ** @see java.lang.ThreadGroup#interrupt()
- ** @see java.lang.ThreadGroup#setDaemon(boolean)
- ** @see java.lang.ThreadGroup#setMaxPriority(int)
- **/
- public void checkAccess(ThreadGroup g) {
- throw new SecurityException("Cannot modify ThreadGroups.");
- }
-
- /** Check if the current thread is allowed to exit the
- ** JVM with the given status.<P>
- **
- ** This method is called from Runtime.exit().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param status the status to exit with
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Runtime#exit()
- ** @see java.lang.Runtime#exit(int)
- **/
- public void checkExit(int status) {
- throw new SecurityException("Cannot exit JVM.");
- }
-
- /** Check if the current thread is allowed to execute the
- ** given program.<P>
- **
- ** This method is called from Runtime.exec().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param program the name of the program to exec
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Runtime#exec(java.lang.String[],java.lang.String[])
- **/
- public void checkExec(String program) {
- throw new SecurityException("Cannot execute programs.");
- }
-
- /** Check if the current thread is allowed to link in the
- ** given native library.<P>
- **
- ** This method is called from Runtime.load() (and hence,
- ** by loadLibrary() as well).<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param filename the full name of the library to load
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Runtime#load(java.lang.String)
- **/
- public void checkLink(String filename) {
- throw new SecurityException("Cannot link native libraries.");
- }
-
- /** Check if the current thread is allowed to read the
- ** given file using the FileDescriptor.<P>
- **
- ** This method is called from
- ** FileInputStream.FileInputStream().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param desc the FileDescriptor representing the file
- ** to access
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.io.FileInputStream#FileInputStream(java.io.FileDescriptor)
- **/
- public void checkRead(FileDescriptor desc) {
- throw new SecurityException("Cannot read files via file descriptors.");
- }
-
- /** Check if the current thread is allowed to read the
- ** given file.<P>
- **
- ** This method is called from
- ** FileInputStream.FileInputStream(),
- ** RandomAccessFile.RandomAccessFile(), File.exists(),
- ** canRead(), isFile(), isDirectory(), lastModified(),
- ** length() and list().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param filename the full name of the file to access
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.io.File
- ** @see java.io.FileInputStream#FileInputStream(java.lang.String)
- ** @see java.io.RandomAccessFile#RandomAccessFile(java.lang.String)
- **/
- public void checkRead(String filename) {
- throw new SecurityException("Cannot read files via file names.");
- }
-
- /** Check if the current thread is allowed to read the
- ** given file. using the given SecurityContext.<P>
- **
- ** I know of no core class that calls this method.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param filename the full name of the file to access
- ** @param securityContext the Security Context to
- ** determine access for.
- ** @exception SecurityException if the operation is not
- ** permitted.
- **/
- public void checkRead(String filename, Object securityContext) {
- throw new SecurityException("Cannot read files via file names.");
- }
-
- /** Check if the current thread is allowed to write to the
- ** given file using the FileDescriptor.<P>
- **
- ** This method is called from
- ** FileOutputStream.FileOutputStream().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param desc the FileDescriptor representing the file
- ** to access
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.io.FileOutputStream#FileOutputStream(java.io.FileDescriptor)
- **/
- public void checkWrite(FileDescriptor desc) {
- throw new SecurityException("Cannot write files via file descriptors.");
- }
-
- /** Check if the current thread is allowed to write to the
- ** given file.<P>
- **
- ** This method is called from
- ** FileOutputStream.FileOutputStream(),
- ** RandomAccessFile.RandomAccessFile(),
- ** File.canWrite(), mkdir(), and renameTo().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param filename the full name of the file to access
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.io.File#canWrite()
- ** @see java.io.File#mkdir()
- ** @see java.io.File#renameTo()
- ** @see java.io.FileOutputStream#FileOutputStream(java.lang.String)
- ** @see java.io.RandomAccessFile#RandomAccessFile(java.lang.String)
- **/
- public void checkWrite(String filename) {
- throw new SecurityException("Cannot write files via file names.");
- }
-
- /** Check if the current thread is allowed to delete the
- ** given file.<P>
- **
- ** This method is called from File.delete().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param filename the full name of the file to delete
- ** @exception SecurityException if th operation is not
- ** permitted.
- ** @see java.io.File#delete()
- **/
- public void checkDelete(String filename) {
- throw new SecurityException("Cannot delete files.");
- }
-
- /** Check if the current thread is allowed to connect to a
- ** given host on a given port.<P>
- **
- ** This method is called from Socket.Socket().
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param host the host to connect to
- ** @param port the port to connect on
- ** @exception SecurityException if the operation is not
- ** permitted
- ** @see java.net.Socket#Socket()
- **/
- public void checkConnect(String host, int port) {
- throw new SecurityException("Cannot make network connections.");
- }
-
- /** Check if the current thread is allowed to connect to a
- ** given host on a given port using a specific security
- ** context to determine access.<P>
- **
- ** This method is not called in the 1.1 core classes.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param host the host to connect to
- ** @param port the port to connect on
- ** @param securityContext the security context to
- ** determine access with
- ** @exception SecurityException if the operation is not
- ** permitted
- **/
- public void checkConnect(String host, int port, Object securityContext) {
- throw new SecurityException("Cannot make network connections.");
- }
-
- /** Check if the current thread is allowed to listen to a
- ** specific port for data.<P>
- **
- ** This method is called by ServerSocket.ServerSocket().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param port the port to listen on
- ** @exception SecurityException if the operation is not
- ** permitted
- ** @see java.net.ServerSocket#ServerSocket(int)
- **/
- public void checkListen(int port) {
- throw new SecurityException("Cannot listen for connections.");
- }
-
- /** Check if the current thread is allowed to accept a
- ** connection from a particular host on a particular
- ** port.<P>
- **
- ** This method is called by ServerSocket.implAccept().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param host the host which wishes to connect
- ** @param port the port the connection will be on
- ** @exception SecurityException if the operation is not
- ** permitted
- ** @see java.net.ServerSocket#accept()
- **/
- public void checkAccept(String host, int port) {
- throw new SecurityException("Cannot accept connections.");
- }
-
- /** Check if the current thread is allowed to read and
- ** write multicast to a particular address.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @XXX where is it called?
- **
- ** @param addr the address to multicast to.
- ** @exception SecurityException if the operation is not
- ** permitted.
- **/
- public void checkMulticast(InetAddress addr) {
- throw new SecurityException("Cannot read or write multicast.");
- }
-
- /** Check if the current thread is allowed to read and
- ** write multicast to a particular address with a
- ** particular ttl value.<P>
- **
- ** SecurityManager's implementation always denies access.<P>
- **
- ** @XXX where is it called?
- **
- ** @XXX what the hell is ttl? Expand abbreviation.
- **
- ** @param addr the address to multicast to.
- ** @param ttl the ttl value to use
- ** @exception SecurityException if the operation is not
- ** permitted.
- **/
- public void checkMulticast(InetAddress addr, byte ttl) {
- throw new SecurityException("Cannot read or write multicast.");
- }
-
- /**
- ** Check if the current thread is allowed to perform an
- ** operation that requires the specified <code>Permission</code>.
- **
- ** @param perm The <code>Permission</code> required.
- ** @exception SecurityException If the operation is not allowed.
- **/
- public void checkPermission(java.security.Permission perm) {
- throw new SecurityException("Operation not allowed");
- }
-
- /**
- ** Check if the current thread is allowed to perform an
- ** operation that requires the specified <code>Permission</code>.
- **
- ** @param perm The <code>Permission</code> required.
- ** @param context A security context
- ** @exception SecurityException If the operation is not allowed.
- ** @since 1.2
- **/
- public void checkPermission(java.security.Permission perm,
- Object context) {
- throw new SecurityException("Operation not allowed");
- }
-
- /** Check if the current thread is allowed to read or
- ** write all the system properties at once.<P>
- **
- ** This method is called by System.getProperties()
- ** and setProperties().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.System#getProperties()
- ** @see java.lang.System#setProperties(java.util.Properties)
- **/
- public void checkPropertiesAccess() {
- throw new SecurityException("Cannot access all system properties at once.");
- }
-
- /** Check if the current thread is allowed to read or
- ** write a particular system property.<P>
- **
- ** This method is called by System.getProperty() and
- ** setProperty().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException is the operation is not
- ** permitted.
- ** @see java.lang.System#getProperty(java.lang.String)
- ** @see java.lang.System#setProperty(java.lang.String,java.lang.String)
- **/
- public void checkPropertyAccess(String name) {
- throw new SecurityException("Cannot access individual system properties.");
- }
-
- /** 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.<P>
- **
- ** This method is called by Window.Window().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param window the window to create
- ** @see java.awt.Window#Window(java.awt.Frame)
- **/
- public boolean checkTopLevelWindow(Object window) {
- return false;
- }
-
- /** Check if the current thread is allowed to create a
- ** print job.<P>
- **
- ** This method is called by Toolkit.getPrintJob(). (I
- ** assume so, at least, it just don't say nothing about
- ** it in the spec.)<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.awt.Toolkit.getPrintJob(java.awt.Frame,java.lang.String,java.util.Properties)
- **/
- public void checkPrintJobAccess() {
- throw new SecurityException("Cannot create print jobs.");
- }
-
- /** Check if the current thread is allowed to use the
- ** system clipboard.<P>
- **
- ** This method is called by Toolkit.getSystemClipboard().
- ** (I assume.)<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.awt.Toolkit#getSystemClipboard()
- **/
- public void checkSystemClipboardAccess() {
- throw new SecurityException("Cannot access the system clipboard.");
- }
-
- /** Check if the current thread is allowed to use the AWT
- ** event queue.<P>
- **
- ** This method is called by Toolkit.getSystemEventQueue().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.awt.Toolkit#getSystemEventQueue()
- **/
- public void checkAwtEventQueueAccess() {
- throw new SecurityException("Cannot access the AWT event queue.");
- }
-
- /** Check if the current thread is allowed to access the
- ** specified package at all.<P>
- **
- ** This method is called by ClassLoader.loadClass() in
- ** user-created ClassLoaders.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param packageName the package name to check access to
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.ClassLoader#loadClass(java.lang.String,boolean)
- **/
- public void checkPackageAccess(String packageName) {
- throw new SecurityException("Cannot access packages via the ClassLoader.");
- }
-
- /** Check if the current thread is allowed to define
- ** classes the specified package. If the class already
- ** created, though, ClassLoader.loadClass() can still
- ** return the Class if checkPackageAccess() checks out.<P>
- **
- ** This method is called by ClassLoader.loadClass() in
- ** user-created ClassLoaders.<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param packageName the package name to check access to
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.ClassLoader#loadClass(java.lang.String,boolean)
- **/
- public void checkPackageDefinition(String packageName) {
- throw new SecurityException("Cannot load classes into any packages via the ClassLoader.");
- }
-
- /** Check if the current thread is allowed to set the
- ** current socket factory.<P>
- **
- ** This method is called by Socket.setSocketImplFactory(),
- ** ServerSocket.setSocketFactory(), and
- ** URL.setURLStreamHandlerFactory().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
- ** @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
- ** @see java.net.URL#setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory)
- **/
- public void checkSetFactory() {
- throw new SecurityException("Cannot set the socket factory.");
- }
-
- /** Check if the current thread is allowed to get certain
- ** types of Methods, Fields and Constructors from a Class
- ** object.<P>
- **
- ** This method is called by Class.getMethod[s](),
- ** Class.getField[s](), Class.getConstructor[s],
- ** Class.getDeclaredMethod[s](),
- ** Class.getDeclaredField[s](), and
- ** Class.getDeclaredConstructor[s]().<P>
- **
- ** SecurityManager's implementation always denies access.
- **
- ** @param c the Class to check
- ** @param memberType the type of members to check
- ** against, either Member.DECLARED or
- ** Member.PUBLIC.
- ** @exception SecurityException if the operation is not
- ** permitted.
- ** @see java.lang.Class
- ** @see java.lang.reflect.Member#DECLARED
- ** @see java.lang.reflect.Member#PUBLIC
- **/
- public void checkMemberAccess(Class c, int memberType) {
- throw new SecurityException("Cannot access members of classes.");
- }
-
- /** Test whether a particular security action may be
- ** taken.
- ** @param action the desired action to take
- ** @exception SecurityException if the action is denied.
- ** @XXX I have no idea what actions must be tested
- ** or where.
- **/
- public void checkSecurityAccess(String action) {
- checkPermission (new java.security.SecurityPermission (action));
- }
-
- /** Get the ThreadGroup that a new Thread should belong
- ** to by default.<P>
- **
- ** Called by Thread.Thread().<P>
- **
- ** SecurityManager's implementation just uses the
- ** ThreadGroup of the current Thread.<P>
- **
- ** <STRONG>Spec Note:</STRONG> it is not clear whether
- ** the new Thread is guaranteed to pass the
- ** checkAccessThreadGroup() test when using this
- ** ThreadGroup. I presume so.
- **
- ** @return the ThreadGroup to put the new Thread into.
- **/
- public ThreadGroup getThreadGroup() {
- return Thread.currentThread().getThreadGroup();
- }
-
- public SecurityManager () {
- if (System.getSecurityManager () != null)
- throw new SecurityException ();
- }
-}
-
+ * 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.checkXXX(<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
+{
+ /**
+ * 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();
+ }
+
+ /**
+ * 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:<br><nl>
+ * <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>
+ * </nl>
+ *
+ * @return the most recent non-system ClassLoader on the execution stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected ClassLoader currentClassLoader()
+ {
+ // XXX should be:
+ // Class c = currentLoadedClass();
+ // return c != null ? c.getClassLoader() : null;
+ return VMSecurityManager.currentClassLoader();
+ }
+
+ /**
+ * 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:<br><nl>
+ * <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>
+ * </nl>
+ *
+ * @return the most recent non-system Class on the execution stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected Class currentLoadedClass()
+ {
+ // XXX Should be:
+ // int i = classLoaderDepth();
+ // return i >= 0 ? getClassContext(i) : null;
+ Class[] c = getClassContext();
+ for (int i = 0; i < c.length; i++)
+ if (c[i].getClassLoader() != null)
+ return c[i];
+ return 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:<br><nl>
+ * <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>
+ * </nl>
+ *
+ * @return the index of the most recent non-system Class on the stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected int classLoaderDepth()
+ {
+ // XXX Check AllPermission first.
+ 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()
+ {
+ // XXX Should be: return AccessController.getContext();
+ return new SecurityContext(getClassContext());
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be: AccessController.checkPermission(perm);
+ throw new SecurityException("Operation not allowed");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // if (! (context instanceof AccessControlContext))
+ // throw new SecurityException("Missing context");
+ // ((AccessControlContext) context).checkPermission(perm);
+
+ throw new SecurityException("Operation not allowed");
+ }
+
+ /**
+ * 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()
+ {
+ // XXX Should be:
+ // checkPermission(new RuntimePermission("createClassLoader"));
+ throw new SecurityException("Cannot create new ClassLoaders.");
+ }
+
+ /**
+ * 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") 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 t the other Thread to check
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if t 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 t)
+ {
+ // XXX Implement this correctly.
+ throw new SecurityException("Cannot modify Threads.");
+ }
+
+ /**
+ * 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") 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 t the other Thread to check
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if t is null
+ * @see Thread#Thread()
+ * @see ThreadGroup#ThreadGroup()
+ * @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)
+ {
+ // XXX Implement this correctly.
+ throw new SecurityException("Cannot modify ThreadGroups.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be: checkPermission(new RuntimePermission("exitVM"));
+ throw new SecurityException("Cannot exit JVM.");
+ }
+
+ /**
+ * 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("&lt;&lt;ALL FILES&gt;&gt;", "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)
+ {
+ // XXX Implement this correctly.
+ throw new SecurityException("Cannot execute programs.");
+ }
+
+ /**
+ * 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.
+ // XXX Should be:
+ // checkPermission(new RuntimePermission("loadLibrary."
+ // + filename.toString()));
+ throw new SecurityException("Cannot link native libraries.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // checkPermission(new RuntimePermission("readFileDescriptor"));
+ throw new SecurityException("Cannot read files via file descriptors.");
+ }
+
+ /**
+ * 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)
+ */
+ public void checkRead(String filename)
+ {
+ // XXX Should be: checkPermission(new FilePermission(filename, "read"));
+ throw new SecurityException("Cannot read files via file names.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // if (! (context instanceof AccessControlContext))
+ // throw new SecurityException("Missing context");
+ // AccessControlContext ac = (AccessControlContext) context;
+ // ac.checkPermission(new FilePermission(filename, "read"));
+ throw new SecurityException("Cannot read files via file names.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // checkPermission(new RuntimePermission("writeFileDescriptor"));
+ throw new SecurityException("Cannot write files via file descriptors.");
+ }
+
+ /**
+ * 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()
+ * @see FileOutputStream#FileOutputStream(String)
+ * @see RandomAccessFile#RandomAccessFile(String)
+ */
+ public void checkWrite(String filename)
+ {
+ // XXX Should be: checkPermission(new FilePermission(filename, "write"));
+ throw new SecurityException("Cannot write files via file names.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be: checkPermission(new FilePermission(filename, "delete"));
+ throw new SecurityException("Cannot delete files.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // if (port == -1)
+ // checkPermission(new SocketPermission(host, "resolve"));
+ // else
+ // checkPermission(new SocketPermission(host + ":" + port, "connect"));
+ throw new SecurityException("Cannot make network connections.");
+ }
+
+ /**
+ * 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 securityContext)
+ {
+ // XXX Should be:
+ // if (! (context instanceof AccessControlContext))
+ // throw new SecurityException("Missing context");
+ // AccessControlContext ac = (AccessControlContext) context;
+ // if (port == -1)
+ // ac.checkPermission(new SocketPermission(host, "resolve"));
+ // else
+ // ac.checkPermission(new SocketPermission(host + ":" +port, "connect"));
+ throw new SecurityException("Cannot make network connections.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // checkPermission(new SocketPermission("localhost:"
+ // + (port == 0 ? "1024-" : "" +port),
+ // "listen"));
+ throw new SecurityException("Cannot listen for connections.");
+ }
+
+ /**
+ * 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.
+ // XXX Should be:
+ // checkPermission(new SocketPermission(host.toString() + ":" + port,
+ // "accept"));
+ throw new SecurityException("Cannot accept connections.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Should be:
+ // checkPermission(new SocketPermission(addr.getHostAddress(),
+ // "accept,connect"));
+ throw new SecurityException("Cannot read or write multicast.");
+ }
+
+ /**
+ *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)
+ {
+ // XXX Should be:
+ // checkPermission(new SocketPermission(addr.getHostAddress(),
+ // "accept,connect"));
+ throw new SecurityException("Cannot read or write multicast.");
+ }
+
+ /**
+ * 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()
+ {
+ // XXX Should be:
+ // checkPermission(new PropertyPermission("*", "read,write"));
+ throw new SecurityException("Cannot access all system properties at once.");
+ }
+
+ /**
+ * 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.
+ *
+ * @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)
+ {
+ // XXX Should be: checkPermission(new PropertyPermission(key, "read"));
+ throw new SecurityException("Cannot access individual system properties.");
+ }
+
+ /**
+ * 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 Window#Window(Frame)
+ */
+ public boolean checkTopLevelWindow(Object window)
+ {
+ // Should be:
+ // if (window == null)
+ // throw new NullPointerException();
+ // try
+ // {
+ // checkPermission(new AWTPermission("showWindowWithoutWarningBanner"));
+ // return true;
+ // }
+ // catch (SecurityException e)
+ // {
+ // return false;
+ // }
+ 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 Toolkit#getPrintJob(Frame, String, Properties)
+ * @since 1.1
+ */
+ public void checkPrintJobAccess()
+ {
+ // XXX Should be: checkPermission(new RuntimePermission("queuePrintJob"));
+ throw new SecurityException("Cannot create print jobs.");
+ }
+
+ /**
+ * 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 Toolkit#getSystemClipboard()
+ * @since 1.1
+ */
+ public void checkSystemClipboardAccess()
+ {
+ // XXX Should be: checkPermission(new AWTPermission("accessClipboard"));
+ throw new SecurityException("Cannot access the system clipboard.");
+ }
+
+ /**
+ * 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 Toolkit#getSystemEventQueue()
+ * @since 1.1
+ */
+ public void checkAwtEventQueueAccess()
+ {
+ // Should be: checkPermission(new AWTPermission("accessEventQueue"));
+ throw new SecurityException("Cannot access the AWT event queue.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Implement this.
+ throw new SecurityException("Cannot access packages via the ClassLoader.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Implement this.
+ throw new SecurityException("Cannot load classes into any packages via the ClassLoader.");
+ }
+
+ /**
+ * 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()
+ {
+ // XXX Should be: checkPermission(new RuntimePermission("setFactory"));
+ throw new SecurityException("Cannot set the socket factory.");
+ }
+
+ /**
+ * 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)
+ {
+ // XXX Implement this.
+ throw new SecurityException("Cannot access members of classes.");
+ }
+
+ /**
+ * 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();
+ }
+} // class SecurityManager
+
+// XXX This class is unnecessary.
class SecurityContext {
Class[] classes;
SecurityContext(Class[] classes) {
diff --git a/java/lang/System.java b/java/lang/System.java
index 9f6283bbe..a1b009467 100644
--- a/java/lang/System.java
+++ b/java/lang/System.java
@@ -38,8 +38,13 @@ exception statement from your version. */
package java.lang;
-import java.io.*;
-import java.util.*;
+import java.io.FileInputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Properties;
+import java.util.PropertyPermission;
import gnu.classpath.Configuration;
/**
@@ -72,9 +77,128 @@ public class System
}
/**
- * Stores the system properties.
+ * The default properties. Read them in once, then stuff them as defaults
+ * into future properties to save time when recreating properties via
+ * <code>setProperties(null)</code>. This should not be modified.
*/
- private static Properties properties;
+ private static final Properties defaultProperties = new Properties();
+ static
+ {
+ VMSystem.insertSystemProperties(defaultProperties);
+ defaultProperties.put("gnu.cpu.endian",
+ isWordsBigEndian() ? "big" : "little");
+
+ // Common encoding aliases. See gnu.java.io.EncodingManager.
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-1",
+ "8859_1");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-2",
+ "8859_2");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-3",
+ "8859_3");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-4",
+ "8859_4");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-5",
+ "8859_5");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-6",
+ "8859_6");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-7",
+ "8859_7");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-8",
+ "8859_8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-9",
+ "8859_9");
+
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-1",
+ "8859_1");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-2",
+ "8859_2");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-3",
+ "8859_3");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-4",
+ "8859_4");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-5",
+ "8859_5");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-6",
+ "8859_6");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-7",
+ "8859_7");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-8",
+ "8859_8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-8859-9",
+ "8859_9");
+
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_1",
+ "8859_1");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_2",
+ "8859_2");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_3",
+ "8859_3");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_4",
+ "8859_4");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_5",
+ "8859_5");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_6",
+ "8859_6");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_7",
+ "8859_7");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_8",
+ "8859_8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso8859_9",
+ "8859_9");
+
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-1",
+ "8859_1");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-2",
+ "8859_2");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-3",
+ "8859_3");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-4",
+ "8859_4");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-5",
+ "8859_5");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-6",
+ "8859_6");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-7",
+ "8859_7");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-8",
+ "8859_8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.iso-latin-9",
+ "8859_9");
+
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin1",
+ "8859_1");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin2",
+ "8859_2");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin3",
+ "8859_3");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin4",
+ "8859_4");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin5",
+ "8859_5");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin6",
+ "8859_6");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin7",
+ "8859_7");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin8",
+ "8859_8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.latin9",
+ "8859_9");
+
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.UTF-8", "UTF8");
+ defaultProperties.put("gnu.java.io.encoding_scheme_alias.utf-8", "UTF8");
+
+ // XXX FIXME - Temp hack for old systems that set the wrong property
+ if (defaultProperties.get("java.io.tmpdir") == null)
+ defaultProperties.put("java.io.tmpdir",
+ defaultProperties.get("java.tmpdir"));
+ }
+
+ /**
+ * Stores the current system properties. This can be modified by
+ * {@link #setProperties(Properties)}, but will never be null, because
+ * setProperties(null) sucks in the default properties.
+ */
+ private static Properties properties = new Properties(defaultProperties);
/**
* The standard InputStream. This is assigned at startup and starts its
@@ -86,8 +210,8 @@ public class System
* other processes or files. That should all be transparent to you,
* however.
*/
- public static final InputStream in;
-
+ public static final InputStream in
+ = new FileInputStream(FileDescriptor.in);
/**
* The standard output PrintStream. This is assigned at startup and
* starts its life perfectly valid. Although it is marked final, you can
@@ -98,8 +222,8 @@ public class System
* output to other processes or files. That should all be transparent to
* you, however.
*/
- public static final PrintStream out;
-
+ public static final PrintStream out
+ = new PrintStream(new FileOutputStream(FileDescriptor.out));
/**
* The standard output PrintStream. This is assigned at startup and
* starts its life perfectly valid. Although it is marked final, you can
@@ -110,25 +234,8 @@ public class System
* output to other processes or files. That should all be transparent to
* you, however.
*/
- public static final PrintStream err;
-
- /**
- * Initialize the properties and I/O streams.
- */
- static
- {
- properties = new Properties();
- VMSystem.insertSystemProperties(properties);
-
- // XXX FIXME - Temp hack for old systems that set the wrong property
- if (properties.get("java.io.tmpdir") == null)
- properties.put("java.io.tmpdir", properties.get("java.tmpdir"));
-
- insertGNUProperties();
- in = new FileInputStream(FileDescriptor.in);
- out = new PrintStream(new FileOutputStream(FileDescriptor.out));
- err = new PrintStream(new FileOutputStream(FileDescriptor.err));
- }
+ public static final PrintStream err
+ = new PrintStream(new FileOutputStream(FileDescriptor.err));
/**
* Set {@link #in} to a new InputStream. This uses some VM magic to change
@@ -138,10 +245,14 @@ public class System
* @param in the new InputStream
* @throws SecurityException if permission is denied
* @since 1.1
- * @XXX Perform security check (which means setIn should probably be in
- * Java, and add setIn0 as native).
*/
- public static native void setIn(InputStream in);
+ public static void setIn(InputStream in)
+ {
+ SecurityManager sm = Runtime.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setIn0(in);
+ }
/**
* Set {@link #out} to a new PrintStream. This uses some VM magic to change
@@ -151,10 +262,14 @@ public class System
* @param out the new PrintStream
* @throws SecurityException if permission is denied
* @since 1.1
- * @XXX Perform security check (which means setOut should probably be in
- * Java, and add setOut0 as native).
*/
- public static native void setOut(PrintStream out);
+ public static void setOut(PrintStream out)
+ {
+ SecurityManager sm = Runtime.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setOut0(out);
+ }
/**
* Set {@link #err} to a new PrintStream. This uses some VM magic to change
@@ -164,10 +279,14 @@ public class System
* @param err the new PrintStream
* @throws SecurityException if permission is denied
* @since 1.1
- * @XXX Perform security check (which means setErr should probably be in
- * Java, and add setErr0 as native).
*/
- public static native void setErr(PrintStream err);
+ public static void setErr(PrintStream err)
+ {
+ SecurityManager sm = Runtime.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setErr0(err);
+ }
/**
* Set the current SecurityManager. If a security manager already exists,
@@ -263,7 +382,7 @@ public class System
* <code>checkPropertiesAccess</code>. Note that a security manager may
* allow getting a single property, but not the entire group.
*
- * <p>The default properties include:
+ * <p>The required properties include:
* <dl>
* <dt>java.version <dd>Java version number
* <dt>java.vendor <dd>Java vendor specific string
@@ -295,6 +414,19 @@ public class System
* <dt>user.dir <dd>User's current working directory
* </dl>
*
+ * In addition, gnu defines several other properties, where ? stands for
+ * each character in '0' through '9':
+ * <dl>
+ * <dt> gnu.cpu.endian <dd>big or little
+ * <dt> gnu.java.io.encoding_scheme_alias.ISO-8859-? <dd>8859_?
+ * <dt> gnu.java.io.encoding_scheme_alias.iso-8859-? <dd>8859_?
+ * <dt> gnu.java.io.encoding_scheme_alias.iso8859_? <dd>8859_?
+ * <dt> gnu.java.io.encoding_scheme_alias.iso-latin-_? <dd>8859_?
+ * <dt> gnu.java.io.encoding_scheme_alias.latin? <dd>8859_?
+ * <dt> gnu.java.io.encoding_scheme_alias.UTF-8 <dd>UTF8
+ * <dt> gnu.java.io.encoding_scheme_alias.utf-8 <dd>UTF8
+ * </dl>
+ *
* @return the system properties, will never be null
* @throws SecurityException if permission is denied
*/
@@ -303,7 +435,6 @@ public class System
SecurityManager sm = Runtime.getSecurityManager();
if (sm != null)
sm.checkPropertiesAccess();
- //XXX Make sure this is not null, and be thread-safe
return properties;
}
@@ -321,7 +452,8 @@ public class System
SecurityManager sm = Runtime.getSecurityManager();
if (sm != null)
sm.checkPropertiesAccess();
- // XXX Special case null
+ if (properties == null)
+ properties = new Properties(defaultProperties);
System.properties = properties;
}
@@ -340,7 +472,6 @@ public class System
SecurityManager sm = Runtime.getSecurityManager();
if (sm != null)
sm.checkPropertyAccess(key);
- // XXX ensure properties is not null, and be thread-safe
return properties.getProperty(key);
}
@@ -360,7 +491,6 @@ public class System
SecurityManager sm = Runtime.getSecurityManager();
if (sm != null)
sm.checkPropertyAccess(key);
- // XXX ensure properties is not null, and be thread-safe
return properties.getProperty(key, def);
}
@@ -381,23 +511,22 @@ public class System
SecurityManager sm = Runtime.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(key, "write"));
- // XXX ensure properties is not null, and be thread-safe
return (String) properties.setProperty(key, value);
}
/**
- * Get an environment variable. <b>WARNING</b>: This is not the preferred
- * way to check properties, nor is it guaranteed to work across all
- * implementations. Use <code>getProperty</code> instead.
+ * This used to get an environment variable, but following Sun's lead,
+ * it now throws an Error. Use <code>getProperty</code> instead.
*
* @param name the name of the environment variable
- * @return the value of the variable, or null
- * @deprecated use {@link #getProperty(String)}
+ * @return this does not return
+ * @throws Error this is not supported
+ * @deprecated use {@link #getProperty(String)}; getenv is not supported
*/
public static String getenv(String name)
{
- //XXX This should be a native method, which actually uses getenv(3).
- return getProperty(name);
+ throw new Error("getenv no longer supported, use properties instead: "
+ + name);
}
/**
@@ -498,94 +627,41 @@ public class System
* @param libname the library name, as used in <code>loadLibrary</code>
* @return the platform-specific mangling of the name
* @since 1.2
- * @XXX Add this method, and its support in VMSystem.
+ */
public static String mapLibraryName(String libname)
{
- return VMSystem.mapLibraryName(libname);
+ // XXX Fix this!!!!
+ return Runtime.nativeGetLibname("", libname);
}
+
+ /**
+ * Detect big-endian systems.
+ *
+ * @return true if the system is big-endian.
*/
+ static native boolean isWordsBigEndian();
/**
- * Add Classpath specific system properties.
- * <br>
- * Current properties:
- * <br>
- * <ul>
- * <li> gnu.cpu.endian - big or little</li>
- * <li> gnu.java.io.encoding_scheme_alias.ISO-8859-? - 8859_?</li>
- * <li> gnu.java.io.encoding_scheme_alias.iso-8859-? - 8859_?</li>
- * <li> gnu.java.io.encoding_scheme_alias.iso8859_? - 8859_?</li>
- * <li> gnu.java.io.encoding_scheme_alias.iso-latin-_? - 8859_?</li>
- * <li> gnu.java.io.encoding_scheme_alias.latin? - 8859_?</li>
- * <li> gnu.java.io.encoding_scheme_alias.UTF-8 - UTF8</li>
- * <li> gnu.java.io.encoding_scheme_alias.utf-8 - UTF8</li>
- * </ul>
- * @see gnu.java.io.EncodingManager
- */
- static void insertGNUProperties()
- {
- properties.put("gnu.cpu.endian",
- isWordsBigEndian() ? "big" : "little");
+ * Set {@link #in} to a new InputStream.
+ *
+ * @param in the new InputStream
+ * @see #setIn(InputStream)
+ */
+ private static native void setIn0(InputStream in);
- // Common encoding aliases. See gnu.java.io.EncodingManager.
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-1", "8859_1");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-2", "8859_2");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-3", "8859_3");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-4", "8859_4");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-5", "8859_5");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-6", "8859_6");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-7", "8859_7");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-8", "8859_8");
- properties.put("gnu.java.io.encoding_scheme_alias.ISO-8859-9", "8859_9");
-
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-1", "8859_1");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-2", "8859_2");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-3", "8859_3");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-4", "8859_4");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-5", "8859_5");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-6", "8859_6");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-7", "8859_7");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-8", "8859_8");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-8859-9", "8859_9");
-
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_1", "8859_1");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_2", "8859_2");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_3", "8859_3");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_4", "8859_4");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_5", "8859_5");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_6", "8859_6");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_7", "8859_7");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_8", "8859_8");
- properties.put("gnu.java.io.encoding_scheme_alias.iso8859_9", "8859_9");
-
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-1", "8859_1");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-2", "8859_2");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-3", "8859_3");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-4", "8859_4");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-5", "8859_5");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-6", "8859_6");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-7", "8859_7");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-8", "8859_8");
- properties.put("gnu.java.io.encoding_scheme_alias.iso-latin-9", "8859_9");
-
- properties.put("gnu.java.io.encoding_scheme_alias.latin1", "8859_1");
- properties.put("gnu.java.io.encoding_scheme_alias.latin2", "8859_2");
- properties.put("gnu.java.io.encoding_scheme_alias.latin3", "8859_3");
- properties.put("gnu.java.io.encoding_scheme_alias.latin4", "8859_4");
- properties.put("gnu.java.io.encoding_scheme_alias.latin5", "8859_5");
- properties.put("gnu.java.io.encoding_scheme_alias.latin6", "8859_6");
- properties.put("gnu.java.io.encoding_scheme_alias.latin7", "8859_7");
- properties.put("gnu.java.io.encoding_scheme_alias.latin8", "8859_8");
- properties.put("gnu.java.io.encoding_scheme_alias.latin9", "8859_9");
-
- properties.put("gnu.java.io.encoding_scheme_alias.UTF-8", "UTF8");
- properties.put("gnu.java.io.encoding_scheme_alias.utf-8", "UTF8");
- }
+ /**
+ * Set {@link #out} to a new PrintStream.
+ *
+ * @param out the new PrintStream
+ * @see #setOut(PrintStream)
+ */
+ private static native void setOut0(PrintStream out);
/**
- * Detect big-endian systems.
+ * Set {@link #err} to a new PrintStream.
*
- * @return true if the system is big-endian.
+ * @param err the new PrintStream
+ * @see #setErr(PrintStream)
*/
- static native boolean isWordsBigEndian();
+ private static native void setErr0(PrintStream err);
}
diff --git a/java/util/PropertyPermission.java b/java/util/PropertyPermission.java
index 8a87c1301..bb03e45f3 100644
--- a/java/util/PropertyPermission.java
+++ b/java/util/PropertyPermission.java
@@ -111,6 +111,7 @@ public final class PropertyPermission extends BasicPermission
*
* @param name the name of the property
* @param actions the action string
+ * @throws NullPointerException if name is null
* @throws IllegalArgumentException if name string contains an
* illegal wildcard or actions string contains an illegal action
* (this includes a null actions string)
@@ -187,16 +188,14 @@ public final class PropertyPermission extends BasicPermission
*/
public boolean implies(Permission p)
{
- if (! (p instanceof PropertyPermission))
- return false;
-
- // We have to check the actions.
- PropertyPermission pp = (PropertyPermission) p;
- if ((pp.actions & ~actions) != 0)
- return false;
-
- // BasicPermission checks for name.
- return super.implies(p);
+ // BasicPermission checks for name and type.
+ if (super.implies(p))
+ {
+ // We have to check the actions.
+ PropertyPermission pp = (PropertyPermission) p;
+ return (pp.actions & ~actions) == 0;
+ }
+ return false;
}
/**
@@ -209,10 +208,7 @@ public final class PropertyPermission extends BasicPermission
*/
public boolean equals(Object obj)
{
- if (! (obj instanceof PropertyPermission))
- return false;
- PropertyPermission p = (PropertyPermission) obj;
- return actions == p.actions && super.equals(p);
+ return super.equals(obj) && actions == ((PropertyPermission) obj).actions;
}
/**
diff --git a/java/util/PropertyPermissionCollection.java b/java/util/PropertyPermissionCollection.java
index 10f2b7e7c..c96560033 100644
--- a/java/util/PropertyPermissionCollection.java
+++ b/java/util/PropertyPermissionCollection.java
@@ -92,16 +92,22 @@ class PropertyPermissionCollection extends PermissionCollection
if (old != null)
{
if ((pp.actions | old.actions) == old.actions)
- pp = old; // Old includes pp.
+ pp = old; // Old implies pp.
else if ((pp.actions | old.actions) != pp.actions)
- // Here pp doesn't include old; the only case left is both actions.
+ // Here pp doesn't imply old; the only case left is both actions.
pp = new PropertyPermission(name, "read,write");
}
permissions.put(name, pp);
}
/**
- * Returns true if this collection implies the given permission.
+ * Returns true if this collection implies the given permission. This even
+ * returns true for this case:
+ * <pre>
+ * collection.add(new PropertyPermission("a.*", "read"));
+ * collection.add(new PropertyPermission("a.b.*", "write"));
+ * collection.implies(new PropertyPermission("a.b.c", "read,write"));
+ * <pre>
*
* @param permission the permission to check
* @return true if it is implied by this
@@ -111,10 +117,13 @@ class PropertyPermissionCollection extends PermissionCollection
if (! (permission instanceof PropertyPermission))
return false;
PropertyPermission toImply = (PropertyPermission) permission;
+ int actions = toImply.actions;
+
if (all_allowed)
{
int all_actions = ((PropertyPermission) permissions.get("*")).actions;
- if ((toImply.actions & ~all_actions) == 0)
+ actions &= ~all_actions;
+ if (actions == 0)
return true;
}
@@ -130,8 +139,12 @@ class PropertyPermissionCollection extends PermissionCollection
{
PropertyPermission forName =
(PropertyPermission) permissions.get(name);
- if (forName != null && (toImply.actions & ~forName.actions) == 0)
- return true;
+ if (forName != null)
+ {
+ actions &= ~forName.actions;
+ if (actions == 0)
+ return true;
+ }
prefixLength = name.lastIndexOf('.', prefixLength);
if (prefixLength < 0)