home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / rmi / RMISecurityManager.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  9.0 KB  |  335 lines

  1. /*
  2.  * @(#)RMISecurityManager.java    1.17 98/03/18
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.rmi;
  16.  
  17. import java.security.AccessController;
  18. import java.security.AccessControlException;
  19. import java.io.IOException;
  20. import java.io.File;
  21. import java.io.FilePermission;
  22. import java.net.InetAddress;
  23. import java.net.SocketPermission;
  24. import java.net.UnknownHostException;
  25. import java.net.URL;
  26. import java.rmi.server.RMIClassLoader;
  27.  
  28. /**
  29.  * <code>RMISecurityManager</code> provides a default security manager
  30.  * for use by RMI applications that need one because they use downloaded
  31.  * code.  RMI's class loader will not download any classes if no security
  32.  * manager has been set.  <code>RMISecurityManager</code> does not apply
  33.  * to applets, which run under the protection of their browser's security
  34.  * manager.<p>
  35.  *
  36.  * To set the <code>RMISecurityManager</code>, add the following to an
  37.  * application's main() method:<p>
  38.  *
  39.  * <pre>
  40.  * System.setSecurityManager(new RMISecurityManager());
  41.  * </pre><p>
  42.  *
  43.  * The <code>RMISecurityManager</code> follows the same policy as the
  44.  * <code>java.lang.SecurityManager</code> class for security check
  45.  * methods that it does not override.
  46.  *
  47.  * @author  Roger Riggs
  48.  * @author  Peter Jones
  49.  * @version 1.17, 03/18/98
  50.  * @since   JDK1.1
  51.  */
  52. public class RMISecurityManager extends SecurityManager {
  53.  
  54.     /**
  55.      * Construct a new <code>RMISecurityManager</code> object.
  56.      */
  57.     public RMISecurityManager() {
  58.     }
  59.  
  60.     /**
  61.      * Return the security context (e.g., a <code>URL</code>).
  62.      */
  63.     public Object getSecurityContext() {
  64.     return RMIClassLoader.getSecurityContext(currentClassLoader());
  65.     }
  66.  
  67.     /**
  68.      * Check access to threads.
  69.      */
  70.     public synchronized void checkAccess(Thread t) {
  71.     super.checkAccess(t);
  72.     }
  73.  
  74.     /**
  75.      * Check access to threads.
  76.      */
  77.     public synchronized void checkAccess(ThreadGroup g) {
  78.     super.checkAccess(g);
  79.     }
  80.  
  81.     /**
  82.      * Check file read access.
  83.      */
  84.     public synchronized void checkRead(String file) {
  85.     try {
  86.         // allow it if the AccessController does
  87.         super.checkRead(file);
  88.         return;
  89.     } catch (SecurityException se) {
  90.     }
  91.  
  92.     // allow if file is inside of security context URL base
  93.     Object url = getSecurityContext();
  94.     if (url != null && url instanceof java.net.URL) {
  95.         checkRead(file, (URL) url);
  96.     } else {
  97.         FilePermission fp = new FilePermission(file, "read");
  98.         throw new AccessControlException("access denied " + fp, fp);
  99.     }
  100.     }
  101.  
  102.     /**
  103.      * Check file read access on behalf of the given context.
  104.      */
  105.     public void checkRead(String file, Object context) {
  106.     checkRead(file);
  107.     if (context != null) {
  108.         if (context instanceof URL) {
  109.         checkRead(file, (URL) context);
  110.         } else {
  111.         FilePermission fp = new FilePermission(file, "read");
  112.         throw new AccessControlException(
  113.             "access denied (unknown context) " + fp, fp);
  114.         }
  115.     }
  116.     }
  117.  
  118.     /**
  119.      * Throw <code>AccessControlException</code> if given file is not
  120.      * within given URL.
  121.      */
  122.     private synchronized void checkRead(String file, URL base) {
  123.     String realPath = null;
  124.     try {
  125.         AccessController.beginPrivileged();
  126.         realPath = (new File(file)).getCanonicalPath();
  127.     } catch (IOException e) {
  128.         FilePermission fp = new FilePermission(file, "read");
  129.         throw new AccessControlException("access denied " + fp, fp);
  130.     } finally {
  131.         AccessController.endPrivileged();
  132.     }
  133.  
  134.     // if base is a "file:" URL, allow reading in that directory
  135.     if (base.getProtocol().equals("file")) {
  136.         String dir = null;
  137.         try {
  138.         AccessController.beginPrivileged();
  139.         dir = (new File(base.getFile()).getCanonicalPath());
  140.         } catch (IOException e) { // shouldn't happen
  141.         FilePermission fp = new FilePermission(file, "read");
  142.         throw new AccessControlException("access denied " + fp, fp);
  143.         } finally {
  144.         AccessController.endPrivileged();
  145.         }
  146.         if (realPath.startsWith(dir)) {
  147.         return;
  148.         }
  149.     }
  150.  
  151.     FilePermission fp = new FilePermission(file, "read");
  152.     throw new AccessControlException("access denied " + fp, fp);
  153.     }
  154.  
  155.     /**
  156.      * Check if a network connection can be made to the given
  157.      * host and port.
  158.      */
  159.     public synchronized void checkConnect(String host, int port) {
  160.     try {
  161.         // allow it if the AccessController does
  162.         super.checkConnect(host, port);
  163.         return;
  164.     } catch (SecurityException se) {
  165.     }
  166.     
  167.     // REMIND: This is only appropriate for sun.* implementations.
  168.     int depth = classDepth("sun.net.www.http.HttpClient");
  169.     if (depth >= 0) {
  170.         // called through sun http protocol handler
  171.         return;
  172.     }
  173.     depth = classDepth("sun.rmi.transport.tcp.TCPChannel");
  174.     if (depth >= 0) {
  175.         // called through sun rmi transport
  176.         return;
  177.     }
  178.  
  179.     Object url = getSecurityContext();
  180.     if (url != null && url instanceof java.net.URL) {
  181.         checkConnect(((URL) url).getHost(), host);
  182.     } else {
  183.         SocketPermission sp =
  184.         new SocketPermission(host + ":" + port, "connect");
  185.         throw new AccessControlException("access denied " + sp, sp);
  186.     }
  187.     }
  188.  
  189.     /**
  190.      * Check if a network connection can be made to the given
  191.      * host and port on behalf of the given context.
  192.      */
  193.     public void checkConnect(String host, int port, Object context) {
  194.     checkConnect(host, port);
  195.     if (context != null) {
  196.         if (context instanceof URL) {
  197.         checkConnect(((URL) context).getHost(), host);
  198.         } else {
  199.         SocketPermission sp =
  200.             new SocketPermission(host + ":" + port, "connect");
  201.         throw new AccessControlException(
  202.             "access denied (unknown context) " + sp, sp);
  203.         }
  204.     }
  205.     }
  206.  
  207.     /**
  208.      * Throw <code>AccessControlException</code> if attempted connection
  209.      * is not to he host that it is acting on behalf of.
  210.      */
  211.     private synchronized void checkConnect(String fromHost, String toHost) {
  212.     InetAddress toHostAddr, fromHostAddr;
  213.     if (!fromHost.equals(toHost)) {
  214.         try {
  215.         // only allow non-matching strings when the IPs match
  216.         try {
  217.             AccessController.beginPrivileged();
  218.             toHostAddr = InetAddress.getByName(toHost);
  219.             fromHostAddr = InetAddress.getByName(fromHost);
  220.         } finally {
  221.             AccessController.endPrivileged();
  222.         }
  223.  
  224.         if (fromHostAddr.equals(toHostAddr)) {
  225.             return;
  226.         } else {
  227.             throw new AccessControlException(
  228.             "connect from " + fromHost +
  229.             " to " + toHost + " denied");
  230.         }
  231.         } catch (UnknownHostException e) {
  232.         throw new AccessControlException(
  233.             "connect from " + fromHost +
  234.             " to " + toHost + " denied");
  235.         }
  236.     } else {
  237.         try {
  238.         // strings match: must have IP
  239.         try {
  240.             AccessController.beginPrivileged();
  241.             toHostAddr = InetAddress.getByName(toHost);
  242.         } finally {
  243.             AccessController.endPrivileged();
  244.         }
  245.         return;
  246.         } catch (UnknownHostException e) {
  247.         throw new AccessControlException(
  248.             "connect from " + fromHost +
  249.             " to " + toHost + " denied");
  250.         }
  251.     }
  252.     }
  253.  
  254.     /**
  255.      * Check if a network connection can be accepted from the
  256.      * given host on the given port.
  257.      */
  258.     public synchronized void checkAccept(String host, int port) {
  259.     try {
  260.         // allow it if the AccessController does
  261.         super.checkAccept(host, port);
  262.         return;
  263.     } catch (SecurityException se) {
  264.     }
  265.  
  266.     if (inClassLoader() && port < 1024) {
  267.         SocketPermission sp =
  268.         new SocketPermission(host + ":" + port, "accept");
  269.         throw new AccessControlException("access denied " + sp, sp);
  270.     }
  271.     }
  272.  
  273.     /**
  274.      * Check access to classes of a given package.
  275.      */
  276.     public synchronized void checkPackageAccess(String pkg) {
  277.     try {
  278.         // allow it if the AccessController does
  279.         super.checkPackageAccess(pkg);
  280.         return;
  281.     } catch (SecurityException se) {
  282.     }
  283.  
  284.     int i = pkg.indexOf('.');
  285.     try {
  286.         AccessController.beginPrivileged();
  287.         while (i > 0) {
  288.         String subpkg = pkg.substring(0, i);
  289.         if (Boolean.getBoolean("package.restrict.access." + subpkg)) {
  290.             throw new AccessControlException(
  291.             "checkaccessdefinition " + pkg);
  292.         }
  293.         i = pkg.indexOf('.', i + 1);
  294.         }
  295.     } finally {
  296.         AccessController.endPrivileged();
  297.     }
  298.     }
  299.  
  300.     /**
  301.      * Check access to defining classes of a given package.
  302.      */
  303.     public synchronized void checkPackageDefinition(String pkg) {
  304.     try {
  305.         // allow it if the AccessController does
  306.         super.checkPackageDefinition(pkg);
  307.         return;
  308.     } catch (SecurityException se) {
  309.     }
  310.  
  311.     int i = pkg.indexOf('.');
  312.     try {
  313.         AccessController.beginPrivileged();
  314.         while (i > 0) {
  315.         String subpkg = pkg.substring(0, i);
  316.         if (Boolean.getBoolean("package.restrict.definition." +
  317.                        subpkg)) {
  318.             throw new AccessControlException(
  319.             "checkpackagedefinition " + pkg);
  320.         }
  321.         i = pkg.indexOf('.', i + 1);
  322.         }
  323.     } finally {
  324.         AccessController.endPrivileged();
  325.     }
  326.     }
  327.  
  328.     /**
  329.      * Return the thread group that new threads should be created in.
  330.      */
  331.     public ThreadGroup getThreadGroup() {
  332.     return Thread.currentThread().getThreadGroup();
  333.     }
  334. }
  335.