home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / RMISecurityManager.java < prev    next >
Text File  |  1997-05-20  |  13KB  |  445 lines

  1. /*
  2.  * @(#)RMISecurityManager.java    1.11 97/05/02
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  */
  21.  
  22. package java.rmi;
  23.  
  24. import java.net.URL;
  25. import java.net.InetAddress;
  26. import java.net.UnknownHostException;
  27. import java.io.FileDescriptor;
  28. import java.rmi.server.RMIClassLoader;
  29.  
  30. /**
  31.  * This class defines a default security policy for RMI applications (not
  32.  * applets).  For code loaded from a class loader, the security manager
  33.  * disables all functions except class definition and access.  This class
  34.  * may be subclassed to implement a different policy.  To set a
  35.  * RMISecurityManager, add the following to an application's main()
  36.  * method: <br>
  37.  * 
  38.  * System.setSecurityManager(new RMISecurityManager()); If no security
  39.  * manager has been set, RMI will only load classes from local system
  40.  * files as defined by CLASSPATH.<p>
  41.  *
  42.  * @version    1.11, 05/02/97
  43.  * @author Roger Riggs
  44.  */
  45. public class RMISecurityManager extends SecurityManager {
  46.     
  47.     /**
  48.      * Construct and initialize.
  49.      */
  50.     public RMISecurityManager() {
  51.     }
  52.  
  53.     /**
  54.      * True if called indirectly from a loaded class.
  55.      */
  56.     private boolean inLoadedClass() {
  57.     return inClassLoader();
  58.     }
  59.  
  60.     /**
  61.      * Returns the security context (e.g., a URL).
  62.      */
  63.     public Object getSecurityContext() {
  64.     return RMIClassLoader.getSecurityContext(currentClassLoader());
  65.     }
  66.  
  67.  
  68.     /**
  69.      * Loaded classes are not allowed to create class loaders, or even
  70.      * execute any of ClassLoader's methods.
  71.      */
  72.     public synchronized void checkCreateClassLoader() {
  73.     if (inLoadedClass()) {
  74.         throw new RMISecurityException("classloader");
  75.     }
  76.     }
  77.  
  78.     /**
  79.      * Loaded classes are not allowed to manipulate threads.
  80.      */
  81.     public synchronized void checkAccess(Thread t) {
  82.     if (inLoadedClass()) {
  83.         throw new RMISecurityException("thread");
  84.     }
  85.     }
  86.  
  87.     /**
  88.      * Loaded classes are not allowed to manipulate thread groups.
  89.      */
  90.     public synchronized void checkAccess(ThreadGroup g) {
  91.     if (inLoadedClass()) {
  92.         throw new RMISecurityException("threadgroup");
  93.     }
  94.     }
  95.  
  96.     /**
  97.      * Loaded classes are not allowed to exit the VM.
  98.      */
  99.     public synchronized void checkExit(int status) {
  100.     if (inLoadedClass()) {
  101.         throw new RMISecurityException("exit", String.valueOf(status));
  102.     }
  103.     }
  104.  
  105.     /**
  106.      * Loaded classes are not allowed to fork processes.
  107.      */
  108.     public synchronized void checkExec(String cmd){
  109.     if (inLoadedClass()) {
  110.         throw new RMISecurityException("exec", cmd);
  111.     }
  112.     }
  113.  
  114.     /**
  115.      * Loaded classes are not allowed to link dynamic libraries.
  116.      */
  117.     public synchronized void checkLink(String lib){
  118.     switch (classLoaderDepth()) {
  119.       case 2: // Runtime.load
  120.       case 3: // System.loadLibrary
  121.         throw new RMISecurityException("link", lib);
  122.       default:
  123.         break;
  124.     }
  125.     }
  126.  
  127.     /**
  128.      * Loaded classes are not allowed to access the system properties list.
  129.      */
  130.     public synchronized void checkPropertiesAccess() {
  131.     if (classLoaderDepth() == 2) {
  132.         throw new RMISecurityException("properties");
  133.     }
  134.     }
  135.  
  136.     /**
  137.      * Loaded classes can access the system property named by <i>key</i>
  138.      * only if its twin <i>key.rmi</i> property is set to true.
  139.      * For example, the property <code>java.home</code> can be read by
  140.      * loaded classes only if <code>java.home.rmi</code> is <code>true</code>.
  141.      */
  142.     public synchronized void checkPropertyAccess(String key) {
  143.     if (classLoaderDepth() == 2) {
  144.         if (!"true".equalsIgnoreCase(System.getProperty(key + ".rmi"))) {
  145.         throw new RMISecurityException("properties");
  146.             }
  147.     }
  148.     }
  149.  
  150.     /**
  151.      * Check if a loaded class can read a particular file.
  152.      */
  153.     public synchronized void checkRead(String file) {
  154.     if (inLoadedClass())
  155.         throw new RMISecurityException("file.read", file);
  156.     }
  157.  
  158.     /**
  159.      * No file reads are valid from a loaded class.
  160.      * @exception  RMISecurityException If called from a loaded class.
  161.      */
  162.     public void checkRead(String file, Object context) {
  163.     if (inLoadedClass())
  164.         throw new RMISecurityException("file.read", file);
  165.     }
  166.  
  167.     /**
  168.      * Check if a loaded class can write a particular file.
  169.      * @exception  RMISecurityException If called from a loaded class.
  170.      */
  171.     public synchronized void checkWrite(String file) {
  172.     if (inLoadedClass()) {
  173.         throw new RMISecurityException("file.write", file);
  174.     }
  175.     }
  176.  
  177.     /**
  178.      * Check if a file with the specified system dependent
  179.      * file name can be deleted.
  180.      * @param file the system dependent file name
  181.      * @exception  RMISecurityException If the file is not found.
  182.      */
  183.     public void checkDelete(String file) {
  184.     if (inLoadedClass()) {
  185.         throw new RMISecurityException("file.delete", file);
  186.     }
  187.     }
  188.  
  189.     /**
  190.      * Loaded classes are not allowed to open descriptors for reading unless
  191.      * it is done through a socket, in which case other access
  192.      * restrictions still apply.
  193.      */
  194.     public synchronized void checkRead(FileDescriptor fd) {
  195.     if ((inLoadedClass() && !inClass("java.net.SocketInputStream"))
  196.         || (!fd.valid()) ) {
  197.         throw new RMISecurityException("fd.read");
  198.     }
  199.     }
  200.  
  201.     /**
  202.      * Loaded classes are not allowed to open descriptors for writing unless
  203.      * it is done through a socket, in which case other access
  204.      * restrictions still apply.
  205.      */
  206.     public synchronized void checkWrite(FileDescriptor fd) {
  207.     if ( (inLoadedClass() && !inClass("java.net.SocketOutputStream")) 
  208.          || (!fd.valid()) ) {
  209.         throw new RMISecurityException("fd.write");
  210.     }
  211.     }
  212.  
  213.     /**
  214.      * For now loaded classes can't listen on any port.
  215.      */
  216.     public synchronized void checkListen(int port) {
  217.     if (inLoadedClass()) {
  218.         throw new RMISecurityException("socket.listen", String.valueOf(port));
  219.     }
  220.     }
  221.  
  222.     /**
  223.      * For now loaded classes can't accept connections on any port.
  224.      */
  225.     public synchronized void checkAccept(String host, int port) {
  226.     if (inLoadedClass()) {
  227.         throw new RMISecurityException("socket.accept", host + ":" + String.valueOf(port));
  228.     }
  229.     }
  230.  
  231.     /**
  232.      * Checks to see if current execution context is allowed to use
  233.      * (join/leave/send/receive) IP multicast (disallowed from loaded classes).
  234.      */
  235.     public void checkMulticast(InetAddress maddr) {
  236.     if (inLoadedClass()) {
  237.         throw new RMISecurityException("checkmulticast");
  238.     }
  239.     }
  240.  
  241.     /**
  242.      * Checks to see if current execution context is allowed to use
  243.      * (join/leave/send/receive) IP multicast (disallowed from loaded classes).
  244.      */
  245.     public void checkMulticast(InetAddress maddr, byte ttl) {
  246.     if (inLoadedClass()) {
  247.         throw new RMISecurityException("checkmulticast");
  248.     }
  249.     }
  250.     
  251.     /**
  252.      * Loaded classes can make connections if called through the RMI transport.
  253.      */
  254.     public synchronized void checkConnect(String host, int port) {
  255.     if (!inLoadedClass()) {
  256.         return;
  257.     }
  258.     
  259.     // REMIND: This is only appropriate for our transport
  260.     // implementation.
  261.     int depth = classDepth("sun.rmi.transport.tcp.TCPChannel");
  262.     if (depth > 1) {
  263.         // Called through our RMI transport
  264.         return;
  265.     } else {
  266.         Object url = getSecurityContext();
  267.         if (url != null && url instanceof java.net.URL) {
  268.         checkConnect(((URL)url).getHost(), host);
  269.         } else {
  270.         throw new RMISecurityException("checkConnect",
  271.                            "To " + host + ":" + port);
  272.         }
  273.     }
  274.     }
  275.     
  276.     private synchronized void checkConnect(String fromHost, String toHost) {
  277.     try {
  278.         inCheck = true;
  279.         InetAddress toHostAddr, fromHostAddr;
  280.         if (!fromHost.equals(toHost)) {
  281.         try {
  282.             // the only time we allow non-matching strings
  283.             // is when IPs and the IPs match.
  284.             toHostAddr = InetAddress.getByName(toHost);
  285.             fromHostAddr = InetAddress.getByName(fromHost);
  286.             
  287.             if (fromHostAddr.equals(toHostAddr)) {
  288.             return;
  289.             } else {
  290.             throw new RMISecurityException("checkConnect",
  291.                                "To " + toHost);
  292.             }
  293.         } catch (UnknownHostException e) {
  294.             throw new RMISecurityException("checkConnect",
  295.                            "To " + toHost);
  296.         }  
  297.         } else {
  298.         try {
  299.             toHostAddr = InetAddress.getByName(toHost);
  300.             
  301.             // strings match: if we have IP, we're homefree, 
  302.             return;
  303.         } catch (UnknownHostException e) {
  304.             throw new RMISecurityException("checkConnect",
  305.                            "To " + toHost);
  306.         }
  307.         }
  308.     } finally {
  309.         inCheck = false;
  310.     }
  311.     }
  312.     
  313.     /**
  314.      * Loaded classes can make connections if
  315.      * called through the RMI transport.
  316.      */
  317.     public void checkConnect(String host, int port, Object context) {
  318.     checkConnect(host, port);
  319.     if (context != null) {
  320.         if (context instanceof URL) {
  321.         checkConnect(((URL)context).getHost(), host);
  322.         } else {
  323.            throw new RMISecurityException("checkConnect (unknown context)",
  324.                            "To " + host);
  325.         }
  326.     }
  327.     }
  328.  
  329.     /**
  330.      * Allow caller to create top-level windows.
  331.      * Allow loaded classes to create windows with warnings.
  332.      */
  333.     public synchronized boolean checkTopLevelWindow(Object window) {
  334.     if (inLoadedClass())
  335.         return false;
  336.     return true;
  337.     }
  338.  
  339.     /**
  340.      * Check if a loaded class can access a package.
  341.      */
  342.     public synchronized void checkPackageAccess(String pkg) {
  343.  
  344.     if (!inLoadedClass())
  345.         return;
  346.     int i = pkg.indexOf('.');
  347.  
  348.     while (i > 0) {
  349.         String subpkg = pkg.substring(0, i);
  350.         if (Boolean.getBoolean("package.restrict.access." + subpkg)) {
  351.         throw new RMISecurityException("checkpackageaccess", pkg);
  352.         }
  353.         i = pkg.indexOf('.', i + 1);
  354.     }
  355.     }
  356.  
  357.     /**
  358.      * Check if a loaded class can define classes in a package.
  359.      */
  360.     public synchronized void checkPackageDefinition(String pkg) {
  361.  
  362.     if (!inLoadedClass())
  363.         return;
  364.     int i = pkg.indexOf('.');
  365.  
  366.     while (i > 0) {
  367.         String subpkg = pkg.substring(0, i);
  368.         if (Boolean.getBoolean("package.restrict.definition." + subpkg)) {
  369.         throw new RMISecurityException("checkpackagedefinition", pkg);
  370.         }
  371.         i = pkg.indexOf('.', i + 1);
  372.     }
  373.     }
  374.  
  375.     /**
  376.      * Check if a loaded class can set a networking-related object factory.
  377.      */
  378.     public synchronized void checkSetFactory() {
  379.     if (inLoadedClass()) {
  380.         throw new RMISecurityException("cannotsetfactory");
  381.     }
  382.     }
  383.  
  384.     /**
  385.      * Disallow printing from loaded classes.
  386.      */
  387.     public void checkPrintJobAccess() {
  388.     if (inLoadedClass()) {
  389.         throw new RMISecurityException("getPrintJob");
  390.     }
  391.     }
  392.  
  393.     /**
  394.      * Checks to see if an client can get access to the System Clipboard
  395.      * (disallowed from loaded classes).
  396.      */
  397.     public void checkSystemClipboardAccess() {
  398.     if (inLoadedClass()) {
  399.         throw new RMISecurityException("checksystemclipboardaccess");
  400.     }
  401.     
  402.     }
  403.  
  404.     /**
  405.      * Checks to see if an client can get access to the AWT event queue
  406.      * (disallowed from loaded classes).
  407.      */
  408.     public void checkAwtEventQueueAccess() {
  409.     if (inLoadedClass()) {
  410.         throw new RMISecurityException("checkawteventqueueaccess");
  411.     }
  412.     }
  413.  
  414.     /**
  415.      * Check if client is allowed reflective access to a member or a set
  416.      * of members for the specified class.  Once initial access is granted,
  417.      * the reflected members can be queried for identifying information, but
  418.      * can only be <strong>used</strong> (via get, set, invoke, or
  419.      * newInstance) with standard Java language access control.
  420.      *
  421.      * <p>The policy is to dent <em>untrusted</em> clients access to
  422.      * <em>declared</em> members of classes other than those loaded via
  423.      * the same class loader.  All other accesses are granted.
  424.      */
  425.     public void checkMemberAccess(Class clazz, int which) {
  426.     if (which != java.lang.reflect.Member.PUBLIC) {
  427.         ClassLoader currentLoader = currentClassLoader();
  428.         if (currentLoader != null) {
  429.         if (currentLoader != clazz.getClassLoader()) {
  430.             throw new RMISecurityException("checkmemberaccess");
  431.         }
  432.         }
  433.     }
  434.     }
  435.  
  436.     /**
  437.      * Loaded classes cannot perform security provider operations.
  438.      */
  439.     public void checkSecurityAccess(String provider) {
  440.     if (inLoadedClass()) {
  441.         throw new RMISecurityException("checksecurityaccess", provider);
  442.     }
  443.     }
  444. }
  445.