| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.rmi.registry;  | 
 | 
 | 
 | 
import java.util.Enumeration;  | 
 | 
import java.util.Hashtable;  | 
 | 
import java.util.MissingResourceException;  | 
 | 
import java.util.ResourceBundle;  | 
 | 
import java.io.FilePermission;  | 
 | 
import java.net.*;  | 
 | 
import java.rmi.*;  | 
 | 
import java.rmi.server.ObjID;  | 
 | 
import java.rmi.server.ServerNotActiveException;  | 
 | 
import java.rmi.registry.Registry;  | 
 | 
import java.rmi.server.RMIClientSocketFactory;  | 
 | 
import java.rmi.server.RMIServerSocketFactory;  | 
 | 
import java.security.AccessControlContext;  | 
 | 
import java.security.AccessController;  | 
 | 
import java.security.CodeSource;  | 
 | 
import java.security.Policy;  | 
 | 
import java.security.PrivilegedActionException;  | 
 | 
import java.security.PrivilegedExceptionAction;  | 
 | 
import java.security.PermissionCollection;  | 
 | 
import java.security.Permissions;  | 
 | 
import java.security.PrivilegedAction;  | 
 | 
import java.security.ProtectionDomain;  | 
 | 
import java.security.Security;  | 
 | 
import java.text.MessageFormat;  | 
 | 
 | 
 | 
import sun.misc.ObjectInputFilter;  | 
 | 
 | 
 | 
import sun.rmi.runtime.Log;  | 
 | 
import sun.rmi.server.UnicastRef;  | 
 | 
import sun.rmi.server.UnicastServerRef;  | 
 | 
import sun.rmi.server.UnicastServerRef2;  | 
 | 
import sun.rmi.transport.LiveRef;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class RegistryImpl extends java.rmi.server.RemoteServer  | 
 | 
        implements Registry  | 
 | 
{ | 
 | 
 | 
 | 
      | 
 | 
    private static final long serialVersionUID = 4666870661827494597L;  | 
 | 
    private Hashtable<String, Remote> bindings  | 
 | 
        = new Hashtable<>(101);  | 
 | 
    private static Hashtable<InetAddress, InetAddress> allowedAccessCache  | 
 | 
        = new Hashtable<>(3);  | 
 | 
    private static RegistryImpl registry;  | 
 | 
    private static ObjID id = new ObjID(ObjID.REGISTRY_ID);  | 
 | 
 | 
 | 
    private static ResourceBundle resources = null;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static final String REGISTRY_FILTER_PROPNAME = "sun.rmi.registry.registryFilter";  | 
 | 
 | 
 | 
      | 
 | 
    private static final int REGISTRY_MAX_DEPTH = 20;  | 
 | 
 | 
 | 
      | 
 | 
    private static final int REGISTRY_MAX_ARRAY_SIZE = 1_000_000;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static final ObjectInputFilter registryFilter =  | 
 | 
            AccessController.doPrivileged((PrivilegedAction<ObjectInputFilter>)RegistryImpl::initRegistryFilter);  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static ObjectInputFilter initRegistryFilter() { | 
 | 
        ObjectInputFilter filter = null;  | 
 | 
        String props = System.getProperty(REGISTRY_FILTER_PROPNAME);  | 
 | 
        if (props == null) { | 
 | 
            props = Security.getProperty(REGISTRY_FILTER_PROPNAME);  | 
 | 
        }  | 
 | 
        if (props != null) { | 
 | 
            filter = ObjectInputFilter.Config.createFilter2(props);  | 
 | 
            Log regLog = Log.getLog("sun.rmi.registry", "registry", -1); | 
 | 
            if (regLog.isLoggable(Log.BRIEF)) { | 
 | 
                regLog.log(Log.BRIEF, "registryFilter = " + filter);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return filter;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public RegistryImpl(int port,  | 
 | 
                        RMIClientSocketFactory csf,  | 
 | 
                        RMIServerSocketFactory ssf)  | 
 | 
        throws RemoteException  | 
 | 
    { | 
 | 
        this(port, csf, ssf, RegistryImpl::registryFilter);  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public RegistryImpl(int port,  | 
 | 
                        RMIClientSocketFactory csf,  | 
 | 
                        RMIServerSocketFactory ssf,  | 
 | 
                        ObjectInputFilter serialFilter)  | 
 | 
        throws RemoteException  | 
 | 
    { | 
 | 
        if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) { | 
 | 
              | 
 | 
            try { | 
 | 
                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | 
 | 
                    public Void run() throws RemoteException { | 
 | 
                        LiveRef lref = new LiveRef(id, port, csf, ssf);  | 
 | 
                        setup(new UnicastServerRef2(lref, serialFilter));  | 
 | 
                        return null;  | 
 | 
                    }  | 
 | 
                }, null, new SocketPermission("localhost:"+port, "listen,accept")); | 
 | 
            } catch (PrivilegedActionException pae) { | 
 | 
                throw (RemoteException)pae.getException();  | 
 | 
            }  | 
 | 
        } else { | 
 | 
            LiveRef lref = new LiveRef(id, port, csf, ssf);  | 
 | 
            setup(new UnicastServerRef2(lref, serialFilter));  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public RegistryImpl(int port)  | 
 | 
        throws RemoteException  | 
 | 
    { | 
 | 
        if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) { | 
 | 
              | 
 | 
            try { | 
 | 
                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | 
 | 
                    public Void run() throws RemoteException { | 
 | 
                        LiveRef lref = new LiveRef(id, port);  | 
 | 
                        setup(new UnicastServerRef(lref, RegistryImpl::registryFilter));  | 
 | 
                        return null;  | 
 | 
                    }  | 
 | 
                }, null, new SocketPermission("localhost:"+port, "listen,accept")); | 
 | 
            } catch (PrivilegedActionException pae) { | 
 | 
                throw (RemoteException)pae.getException();  | 
 | 
            }  | 
 | 
        } else { | 
 | 
            LiveRef lref = new LiveRef(id, port);  | 
 | 
            setup(new UnicastServerRef(lref, RegistryImpl::registryFilter));  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private void setup(UnicastServerRef uref)  | 
 | 
        throws RemoteException  | 
 | 
    { | 
 | 
          | 
 | 
 | 
 | 
         */  | 
 | 
        ref = uref;  | 
 | 
        uref.exportObject(this, null, true);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public Remote lookup(String name)  | 
 | 
        throws RemoteException, NotBoundException  | 
 | 
    { | 
 | 
        synchronized (bindings) { | 
 | 
            Remote obj = bindings.get(name);  | 
 | 
            if (obj == null)  | 
 | 
                throw new NotBoundException(name);  | 
 | 
            return obj;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void bind(String name, Remote obj)  | 
 | 
        throws RemoteException, AlreadyBoundException, AccessException  | 
 | 
    { | 
 | 
        // The access check preventing remote access is done in the skeleton  | 
 | 
          | 
 | 
        synchronized (bindings) { | 
 | 
            Remote curr = bindings.get(name);  | 
 | 
            if (curr != null)  | 
 | 
                throw new AlreadyBoundException(name);  | 
 | 
            bindings.put(name, obj);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void unbind(String name)  | 
 | 
        throws RemoteException, NotBoundException, AccessException  | 
 | 
    { | 
 | 
        // The access check preventing remote access is done in the skeleton  | 
 | 
          | 
 | 
        synchronized (bindings) { | 
 | 
            Remote obj = bindings.get(name);  | 
 | 
            if (obj == null)  | 
 | 
                throw new NotBoundException(name);  | 
 | 
            bindings.remove(name);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void rebind(String name, Remote obj)  | 
 | 
        throws RemoteException, AccessException  | 
 | 
    { | 
 | 
        // The access check preventing remote access is done in the skeleton  | 
 | 
          | 
 | 
        bindings.put(name, obj);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public String[] list()  | 
 | 
        throws RemoteException  | 
 | 
    { | 
 | 
        String[] names;  | 
 | 
        synchronized (bindings) { | 
 | 
            int i = bindings.size();  | 
 | 
            names = new String[i];  | 
 | 
            Enumeration<String> enum_ = bindings.keys();  | 
 | 
            while ((--i) >= 0)  | 
 | 
                names[i] = enum_.nextElement();  | 
 | 
        }  | 
 | 
        return names;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static void checkAccess(String op) throws AccessException { | 
 | 
        try { | 
 | 
              | 
 | 
 | 
 | 
             */  | 
 | 
            final String clientHostName = getClientHost();  | 
 | 
            InetAddress clientHost;  | 
 | 
 | 
 | 
            try { | 
 | 
                clientHost = java.security.AccessController.doPrivileged(  | 
 | 
                    new java.security.PrivilegedExceptionAction<InetAddress>() { | 
 | 
                        public InetAddress run()  | 
 | 
                            throws java.net.UnknownHostException  | 
 | 
                        { | 
 | 
                            return InetAddress.getByName(clientHostName);  | 
 | 
                        }  | 
 | 
                    });  | 
 | 
            } catch (PrivilegedActionException pae) { | 
 | 
                throw (java.net.UnknownHostException) pae.getException();  | 
 | 
            }  | 
 | 
 | 
 | 
              | 
 | 
            if (allowedAccessCache.get(clientHost) == null) { | 
 | 
 | 
 | 
                if (clientHost.isAnyLocalAddress()) { | 
 | 
                    throw new AccessException(  | 
 | 
                        op + " disallowed; origin unknown");  | 
 | 
                }  | 
 | 
 | 
 | 
                try { | 
 | 
                    final InetAddress finalClientHost = clientHost;  | 
 | 
 | 
 | 
                    java.security.AccessController.doPrivileged(  | 
 | 
                        new java.security.PrivilegedExceptionAction<Void>() { | 
 | 
                            public Void run() throws java.io.IOException { | 
 | 
                                  | 
 | 
 | 
 | 
 | 
 | 
                                 */  | 
 | 
                                (new ServerSocket(0, 10, finalClientHost)).close();  | 
 | 
                                allowedAccessCache.put(finalClientHost,  | 
 | 
                                                       finalClientHost);  | 
 | 
                                return null;  | 
 | 
                            }  | 
 | 
                    });  | 
 | 
                } catch (PrivilegedActionException pae) { | 
 | 
                    // must have been an IOException  | 
 | 
 | 
 | 
                    throw new AccessException(  | 
 | 
                        op + " disallowed; origin " +  | 
 | 
                        clientHost + " is non-local host");  | 
 | 
                }  | 
 | 
            }  | 
 | 
        } catch (ServerNotActiveException ex) { | 
 | 
            /*  | 
 | 
             * Local call from this VM: allow access.  | 
 | 
             */  | 
 | 
        } catch (java.net.UnknownHostException ex) { | 
 | 
            throw new AccessException(op + " disallowed; origin is unknown host");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public static ObjID getID() { | 
 | 
        return id;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private static String getTextResource(String key) { | 
 | 
        if (resources == null) { | 
 | 
            try { | 
 | 
                resources = ResourceBundle.getBundle(  | 
 | 
                    "sun.rmi.registry.resources.rmiregistry");  | 
 | 
            } catch (MissingResourceException mre) { | 
 | 
            }  | 
 | 
            if (resources == null) { | 
 | 
                  | 
 | 
                return ("[missing resource file: " + key + "]"); | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        String val = null;  | 
 | 
        try { | 
 | 
            val = resources.getString(key);  | 
 | 
        } catch (MissingResourceException mre) { | 
 | 
        }  | 
 | 
 | 
 | 
        if (val == null) { | 
 | 
            return ("[missing resource: " + key + "]"); | 
 | 
        } else { | 
 | 
            return (val);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static ObjectInputFilter.Status registryFilter(ObjectInputFilter.FilterInfo filterInfo) { | 
 | 
        if (registryFilter != null) { | 
 | 
            ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo);  | 
 | 
            if (status != ObjectInputFilter.Status.UNDECIDED) { | 
 | 
                  | 
 | 
                return status;  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        if (filterInfo.depth() > REGISTRY_MAX_DEPTH) { | 
 | 
            return ObjectInputFilter.Status.REJECTED;  | 
 | 
        }  | 
 | 
        Class<?> clazz = filterInfo.serialClass();  | 
 | 
        if (clazz != null) { | 
 | 
            if (clazz.isArray()) { | 
 | 
                  | 
 | 
                return (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE)  | 
 | 
                    ? ObjectInputFilter.Status.REJECTED  | 
 | 
                    : ObjectInputFilter.Status.UNDECIDED;  | 
 | 
            }  | 
 | 
            if (String.class == clazz  | 
 | 
                    || java.lang.Number.class.isAssignableFrom(clazz)  | 
 | 
                    || Remote.class.isAssignableFrom(clazz)  | 
 | 
                    || java.lang.reflect.Proxy.class.isAssignableFrom(clazz)  | 
 | 
                    || UnicastRef.class.isAssignableFrom(clazz)  | 
 | 
                    || RMIClientSocketFactory.class.isAssignableFrom(clazz)  | 
 | 
                    || RMIServerSocketFactory.class.isAssignableFrom(clazz)  | 
 | 
                    || java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)  | 
 | 
                    || java.rmi.server.UID.class.isAssignableFrom(clazz)) { | 
 | 
                return ObjectInputFilter.Status.ALLOWED;  | 
 | 
            } else { | 
 | 
                return ObjectInputFilter.Status.REJECTED;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return ObjectInputFilter.Status.UNDECIDED;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static void main(String args[])  | 
 | 
    { | 
 | 
        // Create and install the security manager if one is not installed  | 
 | 
          | 
 | 
        if (System.getSecurityManager() == null) { | 
 | 
            System.setSecurityManager(new RMISecurityManager());  | 
 | 
        }  | 
 | 
 | 
 | 
        try { | 
 | 
              | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
             */  | 
 | 
            String envcp = System.getProperty("env.class.path"); | 
 | 
            if (envcp == null) { | 
 | 
                envcp = ".";              | 
 | 
            }  | 
 | 
            URL[] urls = sun.misc.URLClassPath.pathToURLs(envcp);  | 
 | 
            ClassLoader cl = new URLClassLoader(urls);  | 
 | 
 | 
 | 
              | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
             */  | 
 | 
            sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);  | 
 | 
 | 
 | 
            Thread.currentThread().setContextClassLoader(cl);  | 
 | 
 | 
 | 
            final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])  | 
 | 
                                                   : Registry.REGISTRY_PORT;  | 
 | 
            try { | 
 | 
                registry = AccessController.doPrivileged(  | 
 | 
                    new PrivilegedExceptionAction<RegistryImpl>() { | 
 | 
                        public RegistryImpl run() throws RemoteException { | 
 | 
                            return new RegistryImpl(regPort);  | 
 | 
                        }  | 
 | 
                    }, getAccessControlContext(regPort));  | 
 | 
            } catch (PrivilegedActionException ex) { | 
 | 
                throw (RemoteException) ex.getException();  | 
 | 
            }  | 
 | 
 | 
 | 
              | 
 | 
            while (true) { | 
 | 
                try { | 
 | 
                    Thread.sleep(Long.MAX_VALUE);  | 
 | 
                } catch (InterruptedException e) { | 
 | 
                }  | 
 | 
            }  | 
 | 
        } catch (NumberFormatException e) { | 
 | 
            System.err.println(MessageFormat.format(  | 
 | 
                getTextResource("rmiregistry.port.badnumber"), | 
 | 
                args[0] ));  | 
 | 
            System.err.println(MessageFormat.format(  | 
 | 
                getTextResource("rmiregistry.usage"), | 
 | 
                "rmiregistry" ));  | 
 | 
        } catch (Exception e) { | 
 | 
            e.printStackTrace();  | 
 | 
        }  | 
 | 
        System.exit(1);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static AccessControlContext getAccessControlContext(int port) { | 
 | 
          | 
 | 
        PermissionCollection perms = AccessController.doPrivileged(  | 
 | 
            new java.security.PrivilegedAction<PermissionCollection>() { | 
 | 
                public PermissionCollection run() { | 
 | 
                    CodeSource codesource = new CodeSource(null,  | 
 | 
                        (java.security.cert.Certificate[]) null);  | 
 | 
                    Policy p = java.security.Policy.getPolicy();  | 
 | 
                    if (p != null) { | 
 | 
                        return p.getPermissions(codesource);  | 
 | 
                    } else { | 
 | 
                        return new Permissions();  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            });  | 
 | 
 | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        perms.add(new SocketPermission("*", "connect,accept")); | 
 | 
        perms.add(new SocketPermission("localhost:"+port, "listen,accept")); | 
 | 
 | 
 | 
        perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*")); | 
 | 
        perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*")); | 
 | 
 | 
 | 
        perms.add(new FilePermission("<<ALL FILES>>", "read")); | 
 | 
 | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        ProtectionDomain pd = new ProtectionDomain(  | 
 | 
            new CodeSource(null,  | 
 | 
                (java.security.cert.Certificate[]) null), perms);  | 
 | 
        return new AccessControlContext(new ProtectionDomain[] { pd }); | 
 | 
    }  | 
 | 
}  |