jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java
changeset 43211 f264afd5082c
parent 43061 257cac611780
child 45436 152ed642e379
equal deleted inserted replaced
43210:570fbef3a53b 43211:f264afd5082c
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.rmi.registry;
    26 package sun.rmi.registry;
    27 
    27 
       
    28 import java.io.ObjectInputFilter;
    28 import java.nio.file.Path;
    29 import java.nio.file.Path;
    29 import java.nio.file.Paths;
    30 import java.nio.file.Paths;
       
    31 import java.rmi.server.LogStream;
       
    32 import java.security.PrivilegedAction;
       
    33 import java.security.Security;
    30 import java.util.ArrayList;
    34 import java.util.ArrayList;
    31 import java.util.Enumeration;
    35 import java.util.Enumeration;
    32 import java.util.Hashtable;
    36 import java.util.Hashtable;
    33 import java.util.List;
    37 import java.util.List;
    34 import java.util.MissingResourceException;
    38 import java.util.MissingResourceException;
    37 import java.io.FilePermission;
    41 import java.io.FilePermission;
    38 import java.io.IOException;
    42 import java.io.IOException;
    39 import java.net.*;
    43 import java.net.*;
    40 import java.rmi.*;
    44 import java.rmi.*;
    41 import java.rmi.server.ObjID;
    45 import java.rmi.server.ObjID;
    42 import java.rmi.server.RemoteServer;
       
    43 import java.rmi.server.ServerNotActiveException;
    46 import java.rmi.server.ServerNotActiveException;
    44 import java.rmi.registry.Registry;
    47 import java.rmi.registry.Registry;
    45 import java.rmi.server.RMIClientSocketFactory;
    48 import java.rmi.server.RMIClientSocketFactory;
    46 import java.rmi.server.RMIServerSocketFactory;
    49 import java.rmi.server.RMIServerSocketFactory;
    47 import java.security.AccessControlContext;
    50 import java.security.AccessControlContext;
    52 import java.security.PrivilegedExceptionAction;
    55 import java.security.PrivilegedExceptionAction;
    53 import java.security.PermissionCollection;
    56 import java.security.PermissionCollection;
    54 import java.security.Permissions;
    57 import java.security.Permissions;
    55 import java.security.ProtectionDomain;
    58 import java.security.ProtectionDomain;
    56 import java.text.MessageFormat;
    59 import java.text.MessageFormat;
    57 import sun.rmi.server.LoaderHandler;
    60 
       
    61 import sun.rmi.runtime.Log;
       
    62 import sun.rmi.server.UnicastRef;
    58 import sun.rmi.server.UnicastServerRef;
    63 import sun.rmi.server.UnicastServerRef;
    59 import sun.rmi.server.UnicastServerRef2;
    64 import sun.rmi.server.UnicastServerRef2;
    60 import sun.rmi.transport.LiveRef;
    65 import sun.rmi.transport.LiveRef;
    61 import sun.rmi.transport.ObjectTable;
       
    62 import sun.rmi.transport.Target;
       
    63 
    66 
    64 /**
    67 /**
    65  * A "registry" exists on every node that allows RMI connections to
    68  * A "registry" exists on every node that allows RMI connections to
    66  * servers on that node.  The registry on a particular node contains a
    69  * servers on that node.  The registry on a particular node contains a
    67  * transient database that maps names to remote objects.  When the
    70  * transient database that maps names to remote objects.  When the
    89     private static ObjID id = new ObjID(ObjID.REGISTRY_ID);
    92     private static ObjID id = new ObjID(ObjID.REGISTRY_ID);
    90 
    93 
    91     private static ResourceBundle resources = null;
    94     private static ResourceBundle resources = null;
    92 
    95 
    93     /**
    96     /**
       
    97      * Property name of the RMI Registry serial filter to augment
       
    98      * the built-in list of allowed types.
       
    99      * Setting the property in the {@code conf/security/java.security} file
       
   100      * will enable the augmented filter.
       
   101      */
       
   102     private static final String REGISTRY_FILTER_PROPNAME = "sun.rmi.registry.registryFilter";
       
   103 
       
   104     /** Registry max depth of remote invocations. **/
       
   105     private static int REGISTRY_MAX_DEPTH = 5;
       
   106 
       
   107     /** Registry maximum array size in remote invocations. **/
       
   108     private static int REGISTRY_MAX_ARRAY_SIZE = 10000;
       
   109 
       
   110     /**
       
   111      * The registryFilter created from the value of the {@code "sun.rmi.registry.registryFilter"}
       
   112      * property.
       
   113      */
       
   114     private static final ObjectInputFilter registryFilter =
       
   115             AccessController.doPrivileged((PrivilegedAction<ObjectInputFilter>)RegistryImpl::initRegistryFilter);
       
   116 
       
   117     /**
       
   118      * Initialize the registryFilter from the security properties or system property; if any
       
   119      * @return an ObjectInputFilter, or null
       
   120      */
       
   121     @SuppressWarnings("deprecation")
       
   122     private static ObjectInputFilter initRegistryFilter() {
       
   123         ObjectInputFilter filter = null;
       
   124         String props = System.getProperty(REGISTRY_FILTER_PROPNAME);
       
   125         if (props == null) {
       
   126             props = Security.getProperty(REGISTRY_FILTER_PROPNAME);
       
   127         }
       
   128         if (props != null) {
       
   129             filter = ObjectInputFilter.Config.createFilter(props);
       
   130             Log regLog = Log.getLog("sun.rmi.registry", "registry", -1);
       
   131             if (regLog.isLoggable(Log.BRIEF)) {
       
   132                 regLog.log(Log.BRIEF, "registryFilter = " + filter);
       
   133             }
       
   134         }
       
   135         return filter;
       
   136     }
       
   137 
       
   138     /**
    94      * Construct a new RegistryImpl on the specified port with the
   139      * Construct a new RegistryImpl on the specified port with the
    95      * given custom socket factory pair.
   140      * given custom socket factory pair.
    96      */
   141      */
    97     public RegistryImpl(int port,
   142     public RegistryImpl(int port,
    98                         RMIClientSocketFactory csf,
   143                         RMIClientSocketFactory csf,
   103             // grant permission for default port only.
   148             // grant permission for default port only.
   104             try {
   149             try {
   105                 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
   150                 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
   106                     public Void run() throws RemoteException {
   151                     public Void run() throws RemoteException {
   107                         LiveRef lref = new LiveRef(id, port, csf, ssf);
   152                         LiveRef lref = new LiveRef(id, port, csf, ssf);
   108                         setup(new UnicastServerRef2(lref));
   153                         setup(new UnicastServerRef2(lref, RegistryImpl::registryFilter));
   109                         return null;
   154                         return null;
   110                     }
   155                     }
   111                 }, null, new SocketPermission("localhost:"+port, "listen,accept"));
   156                 }, null, new SocketPermission("localhost:"+port, "listen,accept"));
   112             } catch (PrivilegedActionException pae) {
   157             } catch (PrivilegedActionException pae) {
   113                 throw (RemoteException)pae.getException();
   158                 throw (RemoteException)pae.getException();
   114             }
   159             }
   115         } else {
   160         } else {
   116             LiveRef lref = new LiveRef(id, port, csf, ssf);
   161             LiveRef lref = new LiveRef(id, port, csf, ssf);
   117             setup(new UnicastServerRef2(lref));
   162             setup(new UnicastServerRef2(lref, RegistryImpl::registryFilter));
   118         }
   163         }
   119     }
   164     }
   120 
   165 
   121     /**
   166     /**
   122      * Construct a new RegistryImpl on the specified port.
   167      * Construct a new RegistryImpl on the specified port.
   128             // grant permission for default port only.
   173             // grant permission for default port only.
   129             try {
   174             try {
   130                 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
   175                 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
   131                     public Void run() throws RemoteException {
   176                     public Void run() throws RemoteException {
   132                         LiveRef lref = new LiveRef(id, port);
   177                         LiveRef lref = new LiveRef(id, port);
   133                         setup(new UnicastServerRef(lref));
   178                         setup(new UnicastServerRef(lref, RegistryImpl::registryFilter));
   134                         return null;
   179                         return null;
   135                     }
   180                     }
   136                 }, null, new SocketPermission("localhost:"+port, "listen,accept"));
   181                 }, null, new SocketPermission("localhost:"+port, "listen,accept"));
   137             } catch (PrivilegedActionException pae) {
   182             } catch (PrivilegedActionException pae) {
   138                 throw (RemoteException)pae.getException();
   183                 throw (RemoteException)pae.getException();
   139             }
   184             }
   140         } else {
   185         } else {
   141             LiveRef lref = new LiveRef(id, port);
   186             LiveRef lref = new LiveRef(id, port);
   142             setup(new UnicastServerRef(lref));
   187             setup(new UnicastServerRef(lref, RegistryImpl::registryFilter));
   143         }
   188         }
   144     }
   189     }
   145 
   190 
   146     /*
   191     /*
   147      * Create the export the object using the parameter
   192      * Create the export the object using the parameter
   357             } catch (MalformedURLException e) {
   402             } catch (MalformedURLException e) {
   358                 //ignore / skip entry
   403                 //ignore / skip entry
   359             }
   404             }
   360         }
   405         }
   361         return paths.toArray(new URL[0]);
   406         return paths.toArray(new URL[0]);
       
   407     }
       
   408 
       
   409     /**
       
   410      * ObjectInputFilter to filter Registry input objects.
       
   411      * The list of acceptable classes is limited to classes normally
       
   412      * stored in a registry.
       
   413      *
       
   414      * @param filterInfo access to the class, array length, etc.
       
   415      * @return  {@link ObjectInputFilter.Status#ALLOWED} if allowed,
       
   416      *          {@link ObjectInputFilter.Status#REJECTED} if rejected,
       
   417      *          otherwise {@link ObjectInputFilter.Status#UNDECIDED}
       
   418      */
       
   419     private static ObjectInputFilter.Status registryFilter(ObjectInputFilter.FilterInfo filterInfo) {
       
   420         if (registryFilter != null) {
       
   421             ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo);
       
   422             if (status != ObjectInputFilter.Status.UNDECIDED) {
       
   423                 // The Registry filter can override the built-in white-list
       
   424                 return status;
       
   425             }
       
   426         }
       
   427 
       
   428         if (filterInfo.depth() > REGISTRY_MAX_DEPTH) {
       
   429             return ObjectInputFilter.Status.REJECTED;
       
   430         }
       
   431         Class<?> clazz = filterInfo.serialClass();
       
   432         if (clazz != null) {
       
   433             if (clazz.isArray()) {
       
   434                 if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) {
       
   435                     return ObjectInputFilter.Status.REJECTED;
       
   436                 }
       
   437                 do {
       
   438                     // Arrays are allowed depending on the component type
       
   439                     clazz = clazz.getComponentType();
       
   440                 } while (clazz.isArray());
       
   441             }
       
   442             if (clazz.isPrimitive()) {
       
   443                 // Arrays of primitives are allowed
       
   444                 return ObjectInputFilter.Status.ALLOWED;
       
   445             }
       
   446             if (String.class == clazz
       
   447                     || java.lang.Number.class.isAssignableFrom(clazz)
       
   448                     || Remote.class.isAssignableFrom(clazz)
       
   449                     || java.lang.reflect.Proxy.class.isAssignableFrom(clazz)
       
   450                     || UnicastRef.class.isAssignableFrom(clazz)
       
   451                     || RMIClientSocketFactory.class.isAssignableFrom(clazz)
       
   452                     || RMIServerSocketFactory.class.isAssignableFrom(clazz)
       
   453                     || java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)
       
   454                     || java.rmi.server.UID.class.isAssignableFrom(clazz)) {
       
   455                 return ObjectInputFilter.Status.ALLOWED;
       
   456             } else {
       
   457                 return ObjectInputFilter.Status.REJECTED;
       
   458             }
       
   459         }
       
   460         return ObjectInputFilter.Status.UNDECIDED;
   362     }
   461     }
   363 
   462 
   364     /**
   463     /**
   365      * Return a new RegistryImpl on the requested port and export it to serve
   464      * Return a new RegistryImpl on the requested port and export it to serve
   366      * registry requests. A classloader is initialized from the system property
   465      * registry requests. A classloader is initialized from the system property